Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include "llvm/IR/GlobalValue.h"
119#include "llvm/IR/Module.h"
120
121#include "llvm/Support/DynamicLibrary.h"
122#include "llvm/Support/raw_ostream.h"
123#include "llvm/Support/Path.h"
124#include "llvm/Support/Process.h"
125#include "llvm/Object/ELFObjectFile.h"
126#include "llvm/Object/ObjectFile.h"
127#include "llvm/Object/SymbolicFile.h"
128#include "llvm/Support/FileSystem.h"
129
130#include <algorithm>
131#include <iostream>
132#include <cassert>
133#include <map>
134#include <set>
135#include <stdexcept>
136#include <stdint.h>
137#include <fstream>
138#include <sstream>
139#include <string>
140#include <tuple>
141#include <typeinfo>
142#include <unordered_map>
143#include <unordered_set>
144#include <utility>
145#include <vector>
146#include <functional>
147
148#ifndef R__WIN32
149#include <cxxabi.h>
150#define R__DLLEXPORT __attribute__ ((visibility ("default")))
151#include <sys/stat.h>
152#endif
153#include <limits.h>
154#include <stdio.h>
155
156#ifdef __APPLE__
157#include <dlfcn.h>
158#include <mach-o/dyld.h>
159#include <mach-o/loader.h>
160#endif // __APPLE__
161
162#ifdef R__UNIX
163#include <dlfcn.h>
164#endif
165
166#ifdef R__LINUX
167# ifndef _GNU_SOURCE
168# define _GNU_SOURCE
169# endif
170# include <link.h> // dl_iterate_phdr()
171#endif
172
173#if defined(__CYGWIN__)
174#include <sys/cygwin.h>
175#define HMODULE void *
176extern "C" {
177 __declspec(dllimport) void * __stdcall GetCurrentProcess();
178 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
179 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
180}
181#endif
182
183// Fragment copied from LLVM's raw_ostream.cpp
184#if defined(_MSC_VER)
185#ifndef STDIN_FILENO
186# define STDIN_FILENO 0
187#endif
188#ifndef STDOUT_FILENO
189# define STDOUT_FILENO 1
190#endif
191#ifndef STDERR_FILENO
192# define STDERR_FILENO 2
193#endif
194#ifndef R__WIN32
195//#if defined(HAVE_UNISTD_H)
196# include <unistd.h>
197//#endif
198#else
199#include "Windows4Root.h"
200#include <Psapi.h>
201#undef GetModuleFileName
202#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
203#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
204#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
205#define dlclose(library) ::FreeLibrary((HMODULE)library)
206#define R__DLLEXPORT __declspec(dllexport)
207#endif
208#endif
209
210//______________________________________________________________________________
211// These functions are helpers for debugging issues with non-LLVMDEV builds.
212//
213R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
214 return D->getDeclContext();
215}
216R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
217 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
218}
219R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
220 return llvm::dyn_cast<clang::RecordDecl>(DC);
221}
222R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
223 return DC->dumpDeclContext();
224}
225R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
226 return D->dump();
227}
228R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
229 return FD->dump();
230}
232 return ((clang::Decl*)D)->dump();
233}
235 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
236 std::string name;
237 {
238 llvm::raw_string_ostream OS(name);
239 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
240 true /*Qualified*/);
241 }
242 printf("%s\n", name.c_str());
243 }
244}
245//______________________________________________________________________________
246// These functions are helpers for testing issues directly rather than
247// relying on side effects.
248// This is used for the test for ROOT-7462/ROOT-6070
250 return D->isInvalidDecl();
251}
252R__DLLEXPORT bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
253 TClingClassInfo *info( (TClingClassInfo*) input);
254 assert(info && info->IsValid());
255 return info->GetDecl()->isInvalidDecl();
256}
257
258using namespace std;
259using namespace clang;
260using namespace ROOT;
261
262namespace {
263 static const std::string gInterpreterClassDef = R"ICF(
264#undef ClassDef
265#define ClassDef(name, id) \
266_ClassDefInterp_(name,id,virtual,) \
267static int DeclFileLine() { return __LINE__; }
268#undef ClassDefNV
269#define ClassDefNV(name, id) \
270_ClassDefInterp_(name,id,,) \
271static int DeclFileLine() { return __LINE__; }
272#undef ClassDefOverride
273#define ClassDefOverride(name, id) \
274_ClassDefInterp_(name,id,,override) \
275static int DeclFileLine() { return __LINE__; }
276)ICF";
277
278 static const std::string gNonInterpreterClassDef = R"ICF(
279#define __ROOTCLING__ 1
280#undef ClassDef
281#define ClassDef(name,id) \
282_ClassDefOutline_(name,id,virtual,) \
283static int DeclFileLine() { return __LINE__; }
284#undef ClassDefNV
285#define ClassDefNV(name, id)\
286_ClassDefOutline_(name,id,,)\
287static int DeclFileLine() { return __LINE__; }
288#undef ClassDefOverride
289#define ClassDefOverride(name, id)\
290_ClassDefOutline_(name,id,,override)\
291static int DeclFileLine() { return __LINE__; }
292)ICF";
293
294// The macros below use ::Error, so let's ensure it is included
295 static const std::string gClassDefInterpMacro = R"ICF(
296#include "TError.h"
297
298#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
299private: \
300public: \
301 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
302 static const char *Class_Name() { return #name; } \
303 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
304 static Version_t Class_Version() { return id; } \
305 static TClass *Dictionary() { return 0; } \
306 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
307 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
308 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
309 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
310 static const char *DeclFileName() { return __FILE__; } \
311 static int ImplFileLine() { return 0; } \
312 static const char *ImplFileName() { return __FILE__; }
313)ICF";
314}
316
317// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
318// ROOT (which uses rtti)
319
320////////////////////////////////////////////////////////////////////////////////
321/// Print a StackTrace!
322
323extern "C"
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
330
331extern "C" void TCling__RestoreInterpreterMutex(void *delta)
332{
333 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
338/// which is extracted by error messages we get from callback from cling. Return true
339/// when the missing library was autoloaded.
340
341extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
342{
343 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Reset the interpreter lock to the state it had before interpreter-related
348/// calls happened.
349
351{
352 return ((TCling*)gCling)->RewindInterpreterMutex();
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// Lock the interpreter.
357
359{
360 if (gInterpreterMutex) {
362 }
363 return nullptr;
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Unlock the interpreter.
368
370{
371 if (gInterpreterMutex) {
373 }
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
378
379static void TCling__UpdateClassInfo(const NamedDecl* TD)
380{
381 static Bool_t entered = kFALSE;
382 static vector<const NamedDecl*> updateList;
383 Bool_t topLevel;
384
385 if (entered) topLevel = kFALSE;
386 else {
387 entered = kTRUE;
388 topLevel = kTRUE;
389 }
390 if (topLevel) {
391 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
392 } else {
393 // If we are called indirectly from within another call to
394 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
395 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
396 // This allows for the dictionary to be fully populated when we actually
397 // update the TClass object. The updating of the TClass sometimes
398 // (STL containers and when there is an emulated class) forces the building
399 // of the TClass object's real data (which needs the dictionary info).
400 updateList.push_back(TD);
401 }
402 if (topLevel) {
403 while (!updateList.empty()) {
404 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
405 updateList.pop_back();
406 }
407 entered = kFALSE;
408 }
409}
410
411void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
412 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
413 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
414 // Add the constants to the enum type.
415 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
416 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
417 // Get name of the enum type.
418 std::string constbuf;
419 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
420 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
421 llvm::raw_string_ostream stream(constbuf);
422 // Don't trigger fopen of the source file to count lines:
423 Policy.AnonymousTagLocations = false;
424 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
425 }
426 const char* constantName = constbuf.c_str();
427
428 // Get value of the constant.
429 Long64_t value;
430 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
431 if (valAPSInt.isSigned()) {
432 value = valAPSInt.getSExtValue();
433 } else {
434 value = valAPSInt.getZExtValue();
435 }
436
437 // Create the TEnumConstant or update it if existing
438 TEnumConstant* enumConstant = nullptr;
439 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
440 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
441 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
442 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
443 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
444 } else {
445 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
446 }
447
448 // Add the global constants to the list of Globals.
449 if (!cl) {
450 TCollection* globals = gROOT->GetListOfGlobals(false);
451 if (!globals->FindObject(constantName)) {
452 globals->Add(enumConstant);
453 }
454 }
455 }
456 }
457}
458
459TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
460{
461 // Handle new enum declaration for either global and nested enums.
462
463 // Create the enum type.
464 TEnum* enumType = 0;
465 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
466 std::string buf;
467 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
468 // Get name of the enum type.
469 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
470 llvm::raw_string_ostream stream(buf);
471 // Don't trigger fopen of the source file to count lines:
472 Policy.AnonymousTagLocations = false;
473 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
474 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
475 }
476 if (buf.empty()) {
477 return 0;
478 }
479 const char* name = buf.c_str();
480 enumType = new TEnum(name, VD, cl);
481 UpdateEnumConstants(enumType, cl);
482
483 return enumType;
484}
485
486void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
487 // Handle new declaration.
488 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
489
490 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
491
492 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
493 && !dyn_cast<clang::RecordDecl>(D)) return;
494
495 if (isa<clang::FunctionDecl>(D->getDeclContext())
496 || isa<clang::TagDecl>(D->getDeclContext()))
497 return;
498
499 // Don't list templates.
500 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
501 if (RD->getDescribedClassTemplate())
502 return;
503 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
504 if (FD->getDescribedFunctionTemplate())
505 return;
506 }
507
508 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
509 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
511 }
512 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
513
514 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
515 // Mostly just for EnumDecl (the other TagDecl are handled
516 // by the 'RecordDecl' if statement.
518 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
520 }
521
522 // We care about declarations on the global scope.
523 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
524 return;
525
526 // Enums are lazyly created, thus we don not need to handle them here.
527 if (isa<EnumDecl>(ND))
528 return;
529
530 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
531 // scope.
532 if (!(isa<VarDecl>(ND)))
533 return;
534
535 // Skip if already in the list.
536 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
537 return;
538
539 // Put the global constants and global enums in the corresponding lists.
540 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
542 cast<ValueDecl>(ND), 0)));
543 }
544}
545
546extern "C"
548{
549 // We are sure in this context of the type of the interpreter
550 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
551}
552
553extern "C"
554void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
555 ((TCling*)gCling)->UpdateListsOnCommitted(T);
556}
557
558extern "C"
559void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
560 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
561}
562
563extern "C"
564void TCling__InvalidateGlobal(const clang::Decl *D) {
565 ((TCling*)gCling)->InvalidateGlobal(D);
566}
567
568extern "C"
569void TCling__TransactionRollback(const cling::Transaction &T) {
570 ((TCling*)gCling)->TransactionRollback(T);
571}
572
573extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
574 const char* canonicalName) {
575 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
576}
577
578extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
579{
580 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
581}
582
583extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
584 const char* canonicalName) {
585 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
586}
587
588
589extern "C"
590TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
591 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
592}
593
594extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
595 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
596}
597
598extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
599 const char* argv[])
600{
601 auto tcling = new TCling("C++", "cling C++ Interpreter", argv);
602 cling::DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(interpLibHandle);
603 return tcling;
604}
605
607{
608 delete interp;
609}
610
611// Load library containing specified class. Returns 0 in case of error
612// and 1 in case if success.
613extern "C" int TCling__AutoLoadCallback(const char* className)
614{
615 return ((TCling*)gCling)->AutoLoad(className);
616}
617
618extern "C" int TCling__AutoParseCallback(const char* className)
619{
620 return ((TCling*)gCling)->AutoParse(className);
621}
622
623extern "C" const char* TCling__GetClassSharedLibs(const char* className)
624{
625 return ((TCling*)gCling)->GetClassSharedLibs(className);
626}
627
628// Returns 0 for failure 1 for success
629extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
630{
631 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
632}
633
634extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
635{
636 string file(fileName);
637 string opt(options);
638 return gSystem->CompileMacro(file.c_str(), opt.c_str());
639}
640
641extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
642 string &args, string &io, string &fname)
643{
644 string file(fileName);
645 TString f, amode, arguments, aclicio;
646 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
647 mode = amode.Data(); args = arguments.Data();
648 io = aclicio.Data(); fname = f.Data();
649}
650
651//______________________________________________________________________________
652//
653//
654//
655
656#ifdef R__WIN32
657extern "C" {
658 char *__unDName(char *demangled, const char *mangled, int out_len,
659 void * (* pAlloc )(size_t), void (* pFree )(void *),
660 unsigned short int flags);
661}
662#endif
663
664////////////////////////////////////////////////////////////////////////////////
665/// Find a template decl within N nested namespaces, 0<=N<inf
666/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
667/// by the namespace. Example: ns1::ns2::..::nsN::myTemplate
668/// Returns nullptr in case of error
669
670static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
671{
672 using namespace clang;
673 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
674 return FindTemplateInNamespace(*nsd->decls_begin());
675 }
676
677 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
678 return ctd;
679 }
680
681 return nullptr; // something went wrong.
682}
683
684////////////////////////////////////////////////////////////////////////////////
685/// Autoload a library provided the mangled name of a missing symbol.
686
687void* llvmLazyFunctionCreator(const std::string& mangled_name)
688{
689 return ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
690}
691
692//______________________________________________________________________________
693//
694//
695//
696
697int TCling_GenerateDictionary(const std::vector<std::string> &classes,
698 const std::vector<std::string> &headers,
699 const std::vector<std::string> &fwdDecls,
700 const std::vector<std::string> &unknown)
701{
702 //This function automatically creates the "LinkDef.h" file for templated
703 //classes then executes CompileMacro on it.
704 //The name of the file depends on the class name, and it's not generated again
705 //if the file exist.
706 if (classes.empty()) {
707 return 0;
708 }
709 // Use the name of the first class as the main name.
710 const std::string& className = classes[0];
711 //(0) prepare file name
712 TString fileName = "AutoDict_";
713 std::string::const_iterator sIt;
714 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
715 if (*sIt == '<' || *sIt == '>' ||
716 *sIt == ' ' || *sIt == '*' ||
717 *sIt == ',' || *sIt == '&' ||
718 *sIt == ':') {
719 fileName += '_';
720 }
721 else {
722 fileName += *sIt;
723 }
724 }
725 if (classes.size() > 1) {
726 Int_t chk = 0;
727 std::vector<std::string>::const_iterator it = classes.begin();
728 while ((++it) != classes.end()) {
729 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
730 chk = chk * 3 + it->at(cursor);
731 }
732 }
733 fileName += TString::Format("_%u", chk);
734 }
735 fileName += ".cxx";
736 if (gSystem->AccessPathName(fileName) != 0) {
737 //file does not exist
738 //(1) prepare file data
739 // If STL, also request iterators' operators.
740 // vector is special: we need to check whether
741 // vector::iterator is a typedef to pointer or a
742 // class.
743 static const std::set<std::string> sSTLTypes {
744 "vector","list","forward_list","deque","map","unordered_map","multimap",
745 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
746 "queue","priority_queue","stack","iterator"};
747 std::vector<std::string>::const_iterator it;
748 std::string fileContent("");
749 for (it = headers.begin(); it != headers.end(); ++it) {
750 fileContent += "#include \"" + *it + "\"\n";
751 }
752 for (it = unknown.begin(); it != unknown.end(); ++it) {
753 TClass* cl = TClass::GetClass(it->c_str());
754 if (cl && cl->GetDeclFileName()) {
755 TString header = gSystem->BaseName(cl->GetDeclFileName());
757 TString dirbase(gSystem->BaseName(dir));
758 while (dirbase.Length() && dirbase != "."
759 && dirbase != "include" && dirbase != "inc"
760 && dirbase != "prec_stl") {
761 gSystem->PrependPathName(dirbase, header);
762 dir = gSystem->GetDirName(dir);
763 }
764 fileContent += TString("#include \"") + header + "\"\n";
765 }
766 }
767 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
768 fileContent += "class " + *it + ";\n";
769 }
770 fileContent += "#ifdef __CINT__ \n";
771 fileContent += "#pragma link C++ nestedclasses;\n";
772 fileContent += "#pragma link C++ nestedtypedefs;\n";
773 for (it = classes.begin(); it != classes.end(); ++it) {
774 std::string n(*it);
775 size_t posTemplate = n.find('<');
776 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
777 if (posTemplate != std::string::npos) {
778 n.erase(posTemplate, std::string::npos);
779 if (n.compare(0, 5, "std::") == 0) {
780 n.erase(0, 5);
781 }
782 iSTLType = sSTLTypes.find(n);
783 }
784 fileContent += "#pragma link C++ class ";
785 fileContent += *it + "+;\n" ;
786 fileContent += "#pragma link C++ class ";
787 if (iSTLType != sSTLTypes.end()) {
788 // STL class; we cannot (and don't need to) store iterators;
789 // their shadow and the compiler's version don't agree. So
790 // don't ask for the '+'
791 fileContent += *it + "::*;\n" ;
792 }
793 else {
794 // Not an STL class; we need to allow the I/O of contained
795 // classes (now that we have a dictionary for them).
796 fileContent += *it + "::*+;\n" ;
797 }
798 }
799 fileContent += "#endif\n";
800 //end(1)
801 //(2) prepare the file
802 FILE* filePointer;
803 filePointer = fopen(fileName, "w");
804 if (filePointer == NULL) {
805 //can't open a file
806 return 1;
807 }
808 //end(2)
809 //write data into the file
810 fprintf(filePointer, "%s", fileContent.c_str());
811 fclose(filePointer);
812 }
813 //(3) checking if we can compile a macro, if not then cleaning
814 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
815 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
816 Int_t ret = gSystem->CompileMacro(fileName, "k");
817 gErrorIgnoreLevel = oldErrorIgnoreLevel;
818 if (ret == 0) { //can't compile a macro
819 return 2;
820 }
821 //end(3)
822 return 0;
823}
824
825int TCling_GenerateDictionary(const std::string& className,
826 const std::vector<std::string> &headers,
827 const std::vector<std::string> &fwdDecls,
828 const std::vector<std::string> &unknown)
829{
830 //This function automatically creates the "LinkDef.h" file for templated
831 //classes then executes CompileMacro on it.
832 //The name of the file depends on the class name, and it's not generated again
833 //if the file exist.
834 std::vector<std::string> classes;
835 classes.push_back(className);
836 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
837}
838
839//______________________________________________________________________________
840//
841//
842//
843
844// It is a "fantom" method to synchronize user keyboard input
845// and ROOT prompt line (for WIN32)
846const char* fantomline = "TRint::EndOfLineAction();";
847
848//______________________________________________________________________________
849//
850//
851//
852
854
855//______________________________________________________________________________
856//
857// llvm error handler through exceptions; see also cling/UserInterface
858//
859namespace {
860 // Handle fatal llvm errors by throwing an exception.
861 // Yes, throwing exceptions in error handlers is bad.
862 // Doing nothing is pretty terrible, too.
863 void exceptionErrorHandler(void * /*user_data*/,
864 const std::string& reason,
865 bool /*gen_crash_diag*/) {
866 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
867 }
868}
869
870//______________________________________________________________________________
871//
872//
873//
874
875////////////////////////////////////////////////////////////////////////////////
876
877namespace{
878 // An instance of this class causes the diagnostics of clang to be suppressed
879 // during its lifetime
880 class clangDiagSuppr {
881 public:
882 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
883 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
884 fDiagEngine.setIgnoreAllWarnings(true);
885 }
886
887 ~clangDiagSuppr() {
888 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
889 }
890 private:
891 clang::DiagnosticsEngine& fDiagEngine;
892 bool fOldDiagValue;
893 };
894
895}
896
897////////////////////////////////////////////////////////////////////////////////
898/// Allow calling autoparsing from TMetaUtils
899bool TClingLookupHelper__AutoParse(const char *cname)
900{
901 return gCling->AutoParse(cname);
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Try hard to avoid looking up in the Cling database as this could enduce
906/// an unwanted autoparsing.
907
908bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
909 std::string &result)
910{
911 result.clear();
912
913 unsigned long offset = 0;
914 if (strncmp(tname.c_str(), "const ", 6) == 0) {
915 offset = 6;
916 }
917 unsigned long end = tname.length();
918 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
919 if ( tname[end-1]==']' ) {
920 --end;
921 while ( end && tname[end-1]!='[' ) --end;
922 }
923 --end;
924 }
925 std::string innerbuf;
926 const char *inner;
927 if (end != tname.length()) {
928 innerbuf = tname.substr(offset,end-offset);
929 inner = innerbuf.c_str();
930 } else {
931 inner = tname.c_str()+offset;
932 }
933
934 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
935 if (gROOT->GetListOfClasses()->FindObject(inner)
936 || TClassTable::Check(inner,result) ) {
937 // This is a known class.
938 return true;
939 }
940
941 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
942 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
943 if (type) {
944 // This is a raw type and an already loaded typedef.
945 const char *newname = type->GetFullTypeName();
946 if (type->GetType() == kLong64_t) {
947 newname = "Long64_t";
948 } else if (type->GetType() == kULong64_t) {
949 newname = "ULong64_t";
950 }
951 if (strcmp(inner,newname) == 0) {
952 return true;
953 }
954 if (offset) result = "const ";
955 result += newname;
956 if ( end != tname.length() ) {
957 result += tname.substr(end,tname.length()-end);
958 }
959 if (result == tname) result.clear();
960 return true;
961 }
962
963 // Check if the name is an enumerator
964 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
965 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
966 {
967 // We have a scope
968 // All of this C gymnastic is to avoid allocations on the heap
969 const auto enName = lastPos;
970 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
971 char *scopeName = new char[scopeNameSize + 1];
972 strncpy(scopeName, inner, scopeNameSize);
973 scopeName[scopeNameSize] = '\0';
974 // Check if the scope is in the list of classes
975 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
976 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
977 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
978 }
979 // It may still be in one of the loaded protoclasses
980 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
981 auto listOfEnums = scope->GetListOfEnums();
982 if (listOfEnums) { // it could be null: no enumerators in the protoclass
983 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
984 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
985 }
986 }
987 delete [] scopeName;
988 } else
989 {
990 // We don't have any scope: this could only be a global enum
991 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
992 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
993 }
994
995 if (gCling->GetClassSharedLibs(inner))
996 {
997 // This is a class name.
998 return true;
999 }
1000
1001 return false;
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005
1007{
1008 fContent.reserve(size);
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012
1014{
1015 return fContent.c_str();
1016}
1017
1018////////////////////////////////////////////////////////////////////////////////
1019/// Append string to the storage if not added already.
1020
1021inline bool TCling::TUniqueString::Append(const std::string& str)
1022{
1023 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1024 if (notPresent){
1025 fContent+=str;
1026 }
1027 return notPresent;
1028}
1029
1030std::string TCling::ToString(const char* type, void* obj)
1031{
1032 return fInterpreter->toString(type, obj);
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036///\returns true if the module was loaded.
1037static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1038{
1039 // When starting up ROOT, cling would load all modulemap files on the include
1040 // paths. However, in a ROOT session, it is very common to run aclic which
1041 // will invoke rootcling and possibly produce a modulemap and a module in
1042 // the current folder.
1043 //
1044 // Before failing, try loading the modulemap in the current folder and try
1045 // loading the requested module from it.
1046 std::string currentDir = gSystem->WorkingDirectory();
1047 assert(!currentDir.empty());
1049 if (gDebug > 2)
1050 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1051 ModuleName.c_str());
1052
1053 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1054 return interp.loadModule(ModuleName, /*Complain=*/true);
1055}
1056
1057////////////////////////////////////////////////////////////////////////////////
1058/// Loads the C++ modules that we require to run any ROOT program. This is just
1059/// supposed to make a C++ module from a modulemap available to the interpreter.
1060static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1061{
1062 for (const auto &modName : modules)
1063 LoadModule(modName, interp);
1064}
1065
1066static bool IsFromRootCling() {
1067 // rootcling also uses TCling for generating the dictionary ROOT files.
1068 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1069 return foundSymbol;
1070}
1071
1072/// Checks if there is an ASTFile on disk for the given module \c M.
1073static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1074{
1075 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1076
1077 std::string ModuleFileName;
1078 if (!HSOpts.PrebuiltModulePaths.empty())
1079 // Load the module from *only* in the prebuilt module path.
1080 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1081 if (FullFileName)
1082 *FullFileName = ModuleFileName;
1083
1084 return !ModuleFileName.empty();
1085}
1086
1087static bool HaveFullGlobalModuleIndex = false;
1088static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1089{
1090 CompilerInstance &CI = *interp.getCI();
1091 Preprocessor &PP = CI.getPreprocessor();
1092 auto ModuleManager = CI.getModuleManager();
1093 assert(ModuleManager);
1094 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1095 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1096 // HSI.setModuleCachePath(TROOT::GetLibDir().Data());
1097 std::string ModuleIndexPath = TROOT::GetLibDir().Data();
1098 if (ModuleIndexPath.empty())
1099 return nullptr;
1100 // Get an existing global index. This loads it if not already loaded.
1101 ModuleManager->resetForReload();
1102 ModuleManager->loadGlobalIndex();
1103 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1104
1105 // For finding modules needing to be imported for fixit messages,
1106 // we need to make the global index cover all modules, so we do that here.
1107 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1108 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1109 bool RecreateIndex = false;
1110 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1111 Module *TheModule = I->second;
1112 // We want the index only of the prebuilt modules.
1113 if (!HasASTFileOnDisk(TheModule, PP))
1114 continue;
1115 LoadModule(TheModule->Name, interp);
1116 RecreateIndex = true;
1117 }
1118 if (RecreateIndex) {
1119 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1120 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1121
1122 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1123 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1124 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1125 TraverseDecl(TU);
1126 }
1127 bool VisitNamedDecl(NamedDecl *ND) {
1128 if (!ND->isFromASTFile())
1129 return true;
1130 if (!ND->getIdentifier())
1131 return true;
1132
1133 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1134 return true;
1135
1136 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1137 if (TD->isCompleteDefinition())
1138 Register(TD);
1139 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1140 Register(NSD, /*AddSingleEntry=*/ false);
1141 }
1142 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1143 Register(TND);
1144 // FIXME: Add the rest...
1145 return true; // continue decending
1146 }
1147 private:
1148 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1149 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1150 assert(ND->isFromASTFile());
1151 // FIXME: All decls should have an owning module once rootcling
1152 // updates its generated decls from within the LookupHelper & co.
1153 if (!ND->hasOwningModule()) {
1154#ifndef NDEBUG
1155 SourceManager &SM = ND->getASTContext().getSourceManager();
1156 SourceLocation Loc = ND->getLocation();
1157 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1158 (void)FE;
1159 assert(FE->getName().contains("input_line_"));
1160#endif
1161 return;
1162 }
1163
1164 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1165 assert(OwningModule);
1166 assert(!ND->getName().empty() && "Empty name");
1167 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1168 return;
1169 // FIXME: The FileEntry in not stable to serialize.
1170 // FIXME: We might end up with many times with the same module.
1171 // FIXME: We might end up two modules containing a definition.
1172 // FIXME: What do we do if no definition is found.
1173 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1174 }
1175 };
1176 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1177
1178 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1179 CI.getPCHContainerReader(),
1180 ModuleIndexPath,
1181 &IDs));
1182 ModuleManager->resetForReload();
1183 ModuleManager->loadGlobalIndex();
1184 GlobalIndex = ModuleManager->getGlobalIndex();
1185 }
1187 }
1188 return GlobalIndex;
1189}
1190
1191static void RegisterCxxModules(cling::Interpreter &clingInterp)
1192{
1193 if (!clingInterp.getCI()->getLangOpts().Modules)
1194 return;
1195 // Setup core C++ modules if we have any to setup.
1196
1197 // Load libc and stl first.
1198 // Load vcruntime module for windows
1199#ifdef R__WIN32
1200 LoadModule("vcruntime", clingInterp);
1201 LoadModule("services", clingInterp);
1202#endif
1203
1204#ifdef R__MACOSX
1205 LoadModule("Darwin", clingInterp);
1206#else
1207 LoadModule("libc", clingInterp);
1208#endif
1209 LoadModule("std", clingInterp);
1210
1211 LoadModule("_Builtin_intrinsics", clingInterp);
1212
1213 // Load core modules
1214 // This should be vector in order to be able to pass it to LoadModules
1215 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1216 "ROOT_Config",
1217 "ROOT_Rtypes",
1218 "ROOT_Foundation_Stage1_NoRTTI",
1219 "Core",
1220 "Rint",
1221 "RIO"};
1222
1223 LoadModules(CoreModules, clingInterp);
1224
1225 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1226 if (!IsFromRootCling()) {
1227 std::vector<std::string> CommonModules = {"MathCore"};
1228 LoadModules(CommonModules, clingInterp);
1229
1230 // These modules should not be preloaded but they fix issues.
1231 // FIXME: Hist is not a core module but is very entangled to MathCore and
1232 // causes issues.
1233 std::vector<std::string> FIXMEModules = {"Hist"};
1234 LoadModules(FIXMEModules, clingInterp);
1235
1236 clang::CompilerInstance &CI = *clingInterp.getCI();
1237 GlobalModuleIndex *GlobalIndex = nullptr;
1238 // Conservatively enable platform by platform.
1239 bool supportedPlatform =
1240#ifdef R__LINUX
1241 true
1242#elif defined(R__MACOSX)
1243 true
1244#else // Windows
1245 false
1246#endif
1247 ;
1248 // Allow forcefully enabling/disabling the GMI.
1249 llvm::Optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1250 if (envUseGMI.hasValue()) {
1251 if (!envUseGMI->empty() && !ROOT::FoundationUtils::CanConvertEnvValueToBool(*envUseGMI))
1252 ::Warning("TCling__RegisterCxxModules",
1253 "Cannot convert '%s' to bool, setting to false!",
1254 envUseGMI->c_str());
1255
1256 bool value = envUseGMI->empty() || ROOT::FoundationUtils::ConvertEnvValueToBool(*envUseGMI);
1257
1258 if (supportedPlatform == value)
1259 ::Warning("TCling__RegisterCxxModules", "Global module index is%sused already!",
1260 (value) ? " " :" not ");
1261 supportedPlatform = value;
1262 }
1263
1264 if (supportedPlatform) {
1265 loadGlobalModuleIndex(clingInterp);
1266 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1267 // We should investigate how to suppress it completely.
1268 GlobalIndex = CI.getModuleManager()->getGlobalIndex();
1269 }
1270
1271 llvm::StringSet<> KnownModuleFileNames;
1272 if (GlobalIndex)
1273 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1274
1275 clang::Preprocessor &PP = CI.getPreprocessor();
1276 std::vector<std::string> PendingModules;
1277 PendingModules.reserve(256);
1278 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1279 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1280 clang::Module *M = I->second;
1281 assert(M);
1282
1283 // We want to load only already created modules.
1284 std::string FullASTFilePath;
1285 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1286 continue;
1287
1288 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1289 continue;
1290
1291 if (M->IsMissingRequirement)
1292 continue;
1293
1294 if (GlobalIndex)
1295 LoadModule(M->Name, clingInterp);
1296 else {
1297 // FIXME: We may be able to remove those checks as cling::loadModule
1298 // checks if a module was alredy loaded.
1299 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1300 continue; // This is a core module which was already loaded.
1301
1302 // Load system modules now and delay the other modules after we have
1303 // loaded all system ones.
1304 if (M->IsSystem)
1305 LoadModule(M->Name, clingInterp);
1306 else
1307 PendingModules.push_back(M->Name);
1308 }
1309 }
1310 LoadModules(PendingModules, clingInterp);
1311 }
1312
1313 // Check that the gROOT macro was exported by any core module.
1314 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1315
1316 // `ERROR` and `PI` are from loading R related modules, which conflict with
1317 // user's code.
1318 clingInterp.declare(R"CODE(
1319#ifdef PI
1320# undef PI
1321#endif
1322#ifdef ERROR
1323# undef ERROR
1324#endif
1325 )CODE");
1326}
1327
1328static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1329{
1330 std::string PreIncludes;
1331 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1332
1333 // For the list to also include string, we have to include it now.
1334 // rootcling does parts already if needed, e.g. genreflex does not want using
1335 // namespace std.
1336 if (IsFromRootCling()) {
1337 PreIncludes += "#include \"RtypesCore.h\"\n";
1338 } else {
1339 if (!hasCxxModules)
1340 PreIncludes += "#include \"Rtypes.h\"\n";
1341
1342 PreIncludes += gClassDefInterpMacro + "\n"
1343 + gInterpreterClassDef + "\n"
1344 "#undef ClassImp\n"
1345 "#define ClassImp(X);\n";
1346 }
1347 if (!hasCxxModules)
1348 PreIncludes += "#include <string>\n";
1349
1350 // We must include it even when we have modules because it is marked as
1351 // textual in the modulemap due to the nature of the assert header.
1352#ifndef R__WIN32
1353 PreIncludes += "#include <cassert>\n";
1354#endif
1355 PreIncludes += "using namespace std;\n";
1356 clingInterp.declare(PreIncludes);
1357}
1358
1359////////////////////////////////////////////////////////////////////////////////
1360/// Initialize the cling interpreter interface.
1361/// \param argv - array of arguments passed to the cling::Interpreter constructor
1362/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1363
1364TCling::TCling(const char *name, const char *title, const char* const argv[])
1365: TInterpreter(name, title), fMore(0), fGlobalsListSerial(-1), fMapfile(nullptr),
1369{
1370 fPrompt[0] = 0;
1371 const bool fromRootCling = IsFromRootCling();
1372
1373 fCxxModulesEnabled = false;
1374#ifdef R__USE_CXXMODULES
1375 fCxxModulesEnabled = true;
1376#endif
1377
1378 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1379
1380 fTemporaries = new std::vector<cling::Value>();
1381
1382 std::vector<std::string> clingArgsStorage;
1383 clingArgsStorage.push_back("cling4root");
1384 for (const char* const* arg = argv; *arg; ++arg)
1385 clingArgsStorage.push_back(*arg);
1386
1387 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1388 if (!fromRootCling) {
1390
1391 // Add -I early so ASTReader can find the headers.
1392 std::string interpInclude(TROOT::GetEtcDir().Data());
1393 clingArgsStorage.push_back("-I" + interpInclude);
1394
1395 // Add include path to etc/cling.
1396 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1397
1398 // Add the root include directory and etc/ to list searched by default.
1399 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1400
1401 // Add the current path to the include path
1402 // TCling::AddIncludePath(".");
1403
1404 // Attach the PCH (unless we have C++ modules enabled which provide the
1405 // same functionality).
1406 if (!fCxxModulesEnabled) {
1407 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1408 if (gSystem->Getenv("ROOT_PCH")) {
1409 pchFilename = gSystem->Getenv("ROOT_PCH");
1410 }
1411
1412 clingArgsStorage.push_back("-include-pch");
1413 clingArgsStorage.push_back(pchFilename);
1414 }
1415
1416 clingArgsStorage.push_back("-Wno-undefined-inline");
1417 clingArgsStorage.push_back("-fsigned-char");
1418 }
1419
1420 // Process externally passed arguments if present.
1421 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1422 if (EnvOpt.hasValue()) {
1423 StringRef Env(*EnvOpt);
1424 while (!Env.empty()) {
1425 StringRef Arg;
1426 std::tie(Arg, Env) = Env.split(' ');
1427 clingArgsStorage.push_back(Arg.str());
1428 }
1429 }
1430
1431 auto GetEnvVarPath = [](const std::string &EnvVar,
1432 std::vector<std::string> &Paths) {
1433 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1434 if (EnvOpt.hasValue()) {
1435 StringRef Env(*EnvOpt);
1436 while (!Env.empty()) {
1437 StringRef Arg;
1438 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1439 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1440 Paths.push_back(Arg.str());
1441 }
1442 }
1443 };
1444
1445 if (fCxxModulesEnabled) {
1446 std::vector<std::string> Paths;
1447 // ROOT usually knows better where its libraries are. This way we can
1448 // discover modules without having to should thisroot.sh and should fix
1449 // gnuinstall.
1450#ifdef R__WIN32
1451 Paths.push_back(TROOT::GetBinDir().Data());
1452#else
1453 Paths.push_back(TROOT::GetLibDir().Data());
1454#endif
1455 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1456 std::string EnvVarPath;
1457 for (const std::string& P : Paths)
1459 // FIXME: We should make cling -fprebuilt-module-path work.
1460 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1461 }
1462
1463 // FIXME: This only will enable frontend timing reports.
1464 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1465 if (EnvOpt.hasValue())
1466 clingArgsStorage.push_back("-ftime-report");
1467
1468 // Add the overlay file. Note that we cannot factor it out for both root
1469 // and rootcling because rootcling activates modules only if -cxxmodule
1470 // flag is passed.
1471 if (fCxxModulesEnabled && !fromRootCling) {
1472 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1473 std::vector<std::string> ModuleMaps;
1474 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "module.modulemap";
1475 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1476 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1477
1478 std::string cwd = gSystem->WorkingDirectory();
1479 // Give highest precedence of the modulemap in the cwd if any.
1480 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1481 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1482
1483 for (const std::string& M : ModuleMaps)
1484 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1485
1486 std::string ModulesCachePath;
1487 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1488 if (EnvOpt.hasValue()){
1489 StringRef Env(*EnvOpt);
1490 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1491 ModulesCachePath = Env.str();
1492 } else {
1493 ModulesCachePath = TROOT::GetLibDir();
1494 }
1495
1496 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1497 }
1498
1499 std::vector<const char*> interpArgs;
1500 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1501 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1502 interpArgs.push_back(iArg->c_str());
1503
1504 // Activate C++ modules support. If we are running within rootcling, it's up
1505 // to rootcling to set this flag depending on whether it wants to produce
1506 // C++ modules.
1507 TString vfsArg;
1508 if (fCxxModulesEnabled) {
1509 if (!fromRootCling) {
1510 // We only set this flag, rest is done by the CIFactory.
1511 interpArgs.push_back("-fmodules");
1512 interpArgs.push_back("-fno-implicit-module-maps");
1513 // We should never build modules during runtime, so let's enable the
1514 // module build remarks from clang to make it easier to spot when we do
1515 // this by accident.
1516 interpArgs.push_back("-Rmodule-build");
1517 }
1518 // ROOT implements its AutoLoading upon module's link directives. We
1519 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1520 // facilities use the link directive to dynamically load the relevant
1521 // library. So, we need to suppress clang's default autolink behavior.
1522 interpArgs.push_back("-fno-autolink");
1523 }
1524
1525#ifdef R__FAST_MATH
1526 // Same setting as in rootcling_impl.cxx.
1527 interpArgs.push_back("-ffast-math");
1528#endif
1529
1530 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1531 // Add statically injected extra arguments, usually coming from rootcling.
1532 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1533 extraArgs && *extraArgs; ++extraArgs) {
1534 if (!strcmp(*extraArgs, "-resource-dir")) {
1535 // Take the next arg as the llvm resource directory.
1536 llvmResourceDir = *(++extraArgs);
1537 } else {
1538 interpArgs.push_back(*extraArgs);
1539 }
1540 }
1541
1542 for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1543 interpArgs.push_back(arg.c_str());
1544 }
1545
1546 // Add the Rdict module file extension.
1547 cling::Interpreter::ModuleFileExtensions extensions;
1548 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1549 if (!EnvOpt.hasValue())
1550 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1551
1552 fInterpreter = llvm::make_unique<cling::Interpreter>(interpArgs.size(),
1553 &(interpArgs[0]),
1554 llvmResourceDir, extensions);
1555
1556 // Don't check whether modules' files exist.
1557 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
1558
1559 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1560 // to disable spell checking.
1561 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1562
1563 // We need stream that doesn't close its file descriptor, thus we are not
1564 // using llvm::outs. Keeping file descriptor open we will be able to use
1565 // the results in pipes (Savannah #99234).
1566 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1567 fMetaProcessor = llvm::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1568
1571
1572 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1579
1580 // Disallow auto-parsing in rootcling
1581 fIsAutoParsingSuspended = fromRootCling;
1582
1583 ResetAll();
1584
1585 // Enable dynamic lookup
1586 if (!fromRootCling) {
1587 fInterpreter->enableDynamicLookup();
1588 }
1589
1590 // Enable ClinG's DefinitionShadower for ROOT.
1591 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1592
1593 // Attach cling callbacks last; they might need TROOT::fInterpreter
1594 // and should thus not be triggered during the equivalent of
1595 // TROOT::fInterpreter = new TCling;
1596 std::unique_ptr<TClingCallbacks>
1597 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1598 fClingCallbacks = clingCallbacks.get();
1600 fInterpreter->setCallbacks(std::move(clingCallbacks));
1601
1602 if (!fromRootCling) {
1603 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1604 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1605 // e.g. because of an RPATH build.
1606 DLM.addSearchPath(TROOT::GetLibDir().Data());
1607 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1608 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1609 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1610 };
1611 // Initialize the dyld for the llvmLazyFunctionCreator.
1612 DLM.initializeDyld(ShouldPermanentlyIgnore);
1613 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1614 }
1615}
1616
1617
1618////////////////////////////////////////////////////////////////////////////////
1619/// Destroy the interpreter interface.
1620
1622{
1623 // ROOT's atexit functions require the interepreter to be available.
1624 // Run them before shutting down.
1625 if (!IsFromRootCling())
1626 GetInterpreterImpl()->runAtExitFuncs();
1627 fIsShuttingDown = true;
1628 delete fMapfile;
1629 delete fRootmapFiles;
1630 delete fTemporaries;
1631 delete fNormalizedCtxt;
1632 delete fLookupHelper;
1633 gCling = 0;
1634}
1635
1636////////////////////////////////////////////////////////////////////////////////
1637/// Initialize the interpreter, once TROOT::fInterpreter is set.
1638
1640{
1642
1643 // We are set up. Enable ROOT's AutoLoading.
1644 if (IsFromRootCling())
1645 return;
1646
1647 // Read the rules before enabling the auto loading to not inadvertently
1648 // load the libraries for the classes concerned even-though the user is
1649 // *not* using them.
1650 // Note this call must happen before the first call to LoadLibraryMap.
1651 assert(GetRootMapFiles() == 0 && "Must be called before LoadLibraryMap!");
1652 TClass::ReadRules(); // Read the default customization rules ...
1653
1655 SetClassAutoLoading(true);
1656}
1657
1659{
1660 fIsShuttingDown = true;
1661 ResetGlobals();
1662}
1663
1664////////////////////////////////////////////////////////////////////////////////
1665/// Helper to initialize TVirtualStreamerInfo's factor early.
1666/// Use static initialization to insure only one TStreamerInfo is created.
1668{
1669 // Use lambda since SetFactory return void.
1670 auto setFactory = []() {
1672 return kTRUE;
1673 };
1674 static bool doneFactory = setFactory();
1675 return doneFactory; // avoid unused variable warning.
1676}
1677
1678////////////////////////////////////////////////////////////////////////////////
1679/// Register Rdict data for future loading by LoadPCM;
1680
1681void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1682{
1683 if (IsFromRootCling())
1684 return;
1685
1686 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1687 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1688 return;
1689 }
1690
1691 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1692 // a link to a non-existent file.
1693 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1694}
1695
1696////////////////////////////////////////////////////////////////////////////////
1697/// Tries to load a PCM from TFile; returns true on success.
1698
1700{
1701 auto listOfKeys = pcmFile.GetListOfKeys();
1702
1703 // This is an empty pcm
1704 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1705 ((listOfKeys->GetSize() == 1) && // only one, and
1706 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1707 ))) {
1708 return;
1709 }
1710
1711 TObjArray *protoClasses;
1712 if (gDebug > 1)
1713 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1714
1715 TObjArray *enums;
1716 pcmFile.GetObject("__Enums", enums);
1717 if (enums) {
1718 // Cache the pointers
1719 auto listOfGlobals = gROOT->GetListOfGlobals();
1720 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1721 // Loop on enums and then on enum constants
1722 for (auto selEnum : *enums) {
1723 const char *enumScope = selEnum->GetTitle();
1724 const char *enumName = selEnum->GetName();
1725 if (strcmp(enumScope, "") == 0) {
1726 // This is a global enum and is added to the
1727 // list of enums and its constants to the list of globals
1728 if (!listOfEnums->THashList::FindObject(enumName)) {
1729 ((TEnum *)selEnum)->SetClass(nullptr);
1730 listOfEnums->Add(selEnum);
1731 }
1732 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1733 if (!listOfGlobals->FindObject(enumConstant)) {
1734 listOfGlobals->Add(enumConstant);
1735 }
1736 }
1737 } else {
1738 // This enum is in a namespace. A TClass entry is bootstrapped if
1739 // none exists yet and the enum is added to it
1740 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1741 if (!nsTClassEntry) {
1742 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1743 }
1744 auto listOfEnums = nsTClassEntry->fEnums.load();
1745 if (!listOfEnums) {
1746 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1747 // For this case, the list will be immutable once constructed
1748 // (i.e. in this case, by the end of this routine).
1749 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1750 } else {
1751 // namespaces can have enums added to them
1752 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1753 }
1754 }
1755 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1756 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1757 listOfEnums->Add(selEnum);
1758 }
1759 }
1760 }
1761 enums->Clear();
1762 delete enums;
1763 }
1764
1765 pcmFile.GetObject("__ProtoClasses", protoClasses);
1766
1767 if (protoClasses) {
1768 for (auto obj : *protoClasses) {
1769 TProtoClass *proto = (TProtoClass *)obj;
1771 }
1772 // Now that all TClass-es know how to set them up we can update
1773 // existing TClasses, which might cause the creation of e.g. TBaseClass
1774 // objects which in turn requires the creation of TClasses, that could
1775 // come from the PCH, but maybe later in the loop. Instead of resolving
1776 // a dependency graph the addition to the TClassTable above allows us
1777 // to create these dependent TClasses as needed below.
1778 for (auto proto : *protoClasses) {
1779 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1780 // We have an existing TClass object. It might be emulated
1781 // or interpreted; we now have more information available.
1782 // Make that available.
1783 if (existingCl->GetState() != TClass::kHasTClassInit) {
1784 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1785 if (!dict) {
1786 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1787 } else {
1788 // This will replace the existing TClass.
1789 TClass *ncl = (*dict)();
1790 if (ncl)
1791 ncl->PostLoadCheck();
1792 }
1793 }
1794 }
1795 }
1796
1797 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1798 delete protoClasses;
1799 }
1800
1801 TObjArray *dataTypes;
1802 pcmFile.GetObject("__Typedefs", dataTypes);
1803 if (dataTypes) {
1804 for (auto typedf : *dataTypes)
1805 gROOT->GetListOfTypes()->Add(typedf);
1806 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1807 delete dataTypes;
1808 }
1809}
1810
1811////////////////////////////////////////////////////////////////////////////////
1812/// Tries to load a rdict PCM, issues diagnostics if it fails.
1813
1814void TCling::LoadPCM(std::string pcmFileNameFullPath)
1815{
1816 SuspendAutoLoadingRAII autoloadOff(this);
1817 SuspendAutoParsing autoparseOff(this);
1818 assert(!pcmFileNameFullPath.empty());
1819 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1820
1821 // Easier to work with the ROOT interfaces.
1822 TString pcmFileName = pcmFileNameFullPath;
1823
1824 // Prevent the ROOT-PCMs hitting this during auto-load during
1825 // JITting - which will cause recursive compilation.
1826 // Avoid to call the plugin manager at all.
1828
1830 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1831 if (gDebug > 5) {
1832 gDebug -= 5;
1833 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1834 } else {
1835 gDebug = 0;
1836 }
1837
1838 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1839 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1840
1841 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1842 if (pendingRdict != fPendingRdicts.end()) {
1843 llvm::StringRef pcmContent = pendingRdict->second;
1844 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1845 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1846 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1847
1848 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1849 LoadPCMImpl(pcmMemFile);
1850 fPendingRdicts.erase(pendingRdict);
1851
1852 return;
1853 }
1854
1855 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1856 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1857 pcmFileNameFullPath.data());
1858 if (!fPendingRdicts.empty())
1859 for (const auto &rdict : fPendingRdicts)
1860 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1861 rdict.first.c_str());
1862 return;
1863 }
1864
1865 if (!gROOT->IsRootFile(pcmFileName)) {
1866 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1867 return;
1868 }
1869 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1870 LoadPCMImpl(pcmFile);
1871}
1872
1873//______________________________________________________________________________
1874
1875namespace {
1876 using namespace clang;
1877
1878 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1879 // This class is to be considered an helper for autoparsing.
1880 // It visits the AST and marks all classes (in all of their redeclarations)
1881 // with the setHasExternalLexicalStorage method.
1882 public:
1883 bool VisitRecordDecl(clang::RecordDecl* rcd){
1884 if (gDebug > 2)
1885 Info("ExtLexicalStorageAdder",
1886 "Adding external lexical storage to class %s",
1887 rcd->getNameAsString().c_str());
1888 auto reDeclPtr = rcd->getMostRecentDecl();
1889 do {
1890 reDeclPtr->setHasExternalLexicalStorage();
1891 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1892
1893 return false;
1894 }
1895 };
1896
1897
1898}
1899
1900////////////////////////////////////////////////////////////////////////////////
1901///\returns true if the module map was loaded, false on error or if the map was
1902/// already loaded.
1903bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1904 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1905{
1906 assert(llvm::sys::path::is_absolute(FullPath));
1907 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1908 FileManager &FM = PP.getFileManager();
1909 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1910 // We should look for modulemap files there too.
1911 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1912 if (DE) {
1913 HeaderSearch &HS = PP.getHeaderSearchInfo();
1914 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1915 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1916 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1917 if (!pathExists)
1918 HSOpts.AddPrebuiltModulePath(FullPath);
1919 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1920 // because its internal call to getFile has CacheFailure set to true.
1921 // In our case, modulemaps can appear any time due to ACLiC.
1922 // Code copied from HS.lookupModuleMapFile.
1923 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1924 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1925 const FileEntry *FE = FM.getFile(ModuleMapFileName, /*openFile*/ false,
1926 /*CacheFailure*/ false);
1927
1928 // FIXME: Calling IsLoaded is slow! Replace this with the appropriate
1929 // call to the clang::ModuleMap class.
1930 if (FE && !this->IsLoaded(FE->getName().data())) {
1931 if (!HS.loadModuleMapFile(FE, /*IsSystem*/ false))
1932 return true;
1933 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1934 }
1935 }
1936 return false;
1937}
1938
1939////////////////////////////////////////////////////////////////////////////////
1940/// List of dicts that have the PCM information already in the PCH.
1941static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1942 "libRint",
1943 "libThread",
1944 "libRIO",
1945 "libImt",
1946 "libMultiProc",
1947 "libcomplexDict",
1948 "libdequeDict",
1949 "liblistDict",
1950 "libforward_listDict",
1951 "libvectorDict",
1952 "libmapDict",
1953 "libmultimap2Dict",
1954 "libmap2Dict",
1955 "libmultimapDict",
1956 "libsetDict",
1957 "libmultisetDict",
1958 "libunordered_setDict",
1959 "libunordered_multisetDict",
1960 "libunordered_mapDict",
1961 "libunordered_multimapDict",
1962 "libvalarrayDict",
1963 "G__GenVector32",
1964 "G__Smatrix32"};
1965
1966static void PrintDlError(const char *dyLibName, const char *modulename)
1967{
1968#ifdef R__WIN32
1969 char dyLibError[1000];
1970 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1971 dyLibError, sizeof(dyLibError), NULL);
1972#else
1973 const char *dyLibError = dlerror();
1974#endif
1975 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1976 (dyLibError) ? dyLibError : "");
1977}
1978
1979////////////////////////////////////////////////////////////////////////////////
1980// Update all the TClass registered in fClassesToUpdate
1981
1983{
1984 while (!fClassesToUpdate.empty()) {
1985 TClass *oldcl = fClassesToUpdate.back().first;
1986 // If somehow the TClass has already been loaded (maybe it was registered several time),
1987 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1988 // maybe even kForwardDeclared and needs to replaced.
1989 if (oldcl->GetState() != TClass::kHasTClassInit) {
1990 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1991 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1992 fClassesToUpdate.pop_back();
1993 // Calling func could manipulate the list so, let maintain the list
1994 // then call the dictionary function.
1995 TClass *ncl = dict();
1996 if (ncl) ncl->PostLoadCheck();
1997 } else {
1998 fClassesToUpdate.pop_back();
1999 }
2000 }
2001}
2002////////////////////////////////////////////////////////////////////////////////
2003/// Inject the module named "modulename" into cling; load all headers.
2004/// headers is a 0-terminated array of header files to #include after
2005/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2006/// entries (or %PATH% on Windows).
2007/// This function gets called by the static initialization of dictionary
2008/// libraries.
2009/// The payload code is injected "as is" in the interpreter.
2010/// The value of 'triggerFunc' is used to find the shared library location.
2011
2012void TCling::RegisterModule(const char* modulename,
2013 const char** headers,
2014 const char** includePaths,
2015 const char* payloadCode,
2016 const char* fwdDeclsCode,
2017 void (*triggerFunc)(),
2018 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2019 const char** classesHeaders,
2020 Bool_t lateRegistration /*=false*/,
2021 Bool_t hasCxxModule /*=false*/)
2022{
2023 const bool fromRootCling = IsFromRootCling();
2024 // We need the dictionary initialization but we don't want to inject the
2025 // declarations into the interpreter, except for those we really need for
2026 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2027 if (fromRootCling) return;
2028
2029 // When we cannot provide a module for the library we should enable header
2030 // parsing. This 'mixed' mode ensures gradual migration to modules.
2031 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2032 fHeaderParsingOnDemand = !hasCxxModule;
2033
2034 // Treat Aclic Libs in a special way. Do not delay the parsing.
2035 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2036 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2037 if (hasHeaderParsingOnDemand && isACLiC) {
2038 if (gDebug>1)
2039 Info("TCling::RegisterModule",
2040 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2041 hasHeaderParsingOnDemand = false;
2042 }
2043
2044
2045 // Make sure we relookup symbols that were search for before we loaded
2046 // their autoparse information. We could be more subtil and remove only
2047 // the failed one or only the one in this module, but for now this is
2048 // better than nothing.
2049 fLookedUpClasses.clear();
2050
2051 // Make sure we do not set off AutoLoading or autoparsing during the
2052 // module registration!
2053 SuspendAutoLoadingRAII autoLoadOff(this);
2054
2055 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2056 TCling::AddIncludePath(*inclPath);
2057 }
2058 cling::Transaction* T = 0;
2059 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2060 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2061 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2062 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2063 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2064 assert(cling::Interpreter::kSuccess == compRes &&
2065 "A fwd declaration could not be compiled");
2066 if (compRes!=cling::Interpreter::kSuccess){
2067 Warning("TCling::RegisterModule",
2068 "Problems in declaring string '%s' were encountered.",
2069 fwdDecl.c_str()) ;
2070 continue;
2071 }
2072
2073 // Drill through namespaces recursively until the template is found
2074 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2075 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2076 }
2077
2078 }
2079
2080 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2081 // This is used to give Sema the same view on ACLiC'ed files (which
2082 // are then #included through the dictionary) as rootcling had.
2083 TString code = gNonInterpreterClassDef;
2084 if (payloadCode)
2085 code += payloadCode;
2086
2087 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2088 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2089
2090 if (dyLibName.empty()) {
2091 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2092 return;
2093 }
2094
2095 // The triggerFunc may not be in a shared object but in an executable.
2096 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2097
2098 bool wasDlopened = false;
2099
2100 // If this call happens after dlopen has finished (i.e. late registration)
2101 // there is no need to dlopen the library recursively. See ROOT-8437 where
2102 // the dyLibName would correspond to the binary.
2103 if (!lateRegistration) {
2104
2105 if (isSharedLib) {
2106 // We need to open the dictionary shared library, to resolve symbols
2107 // requested by the JIT from it: as the library is currently being dlopen'ed,
2108 // its symbols are not yet reachable from the process.
2109 // Recursive dlopen seems to work just fine.
2110 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2111 if (dyLibHandle) {
2112 fRegisterModuleDyLibs.push_back(dyLibHandle);
2113 wasDlopened = true;
2114 } else {
2115 PrintDlError(dyLibName.c_str(), modulename);
2116 }
2117 }
2118 } // if (!lateRegistration)
2119
2120 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2121 // We now parse the forward declarations. All the classes are then modified
2122 // in order for them to have an external lexical storage.
2123 std::string fwdDeclsCodeLessEnums;
2124 {
2125 // Search for enum forward decls and only declare them if no
2126 // declaration exists yet.
2127 std::string fwdDeclsLine;
2128 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2129 std::vector<std::string> scopes;
2130 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2131 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2132 // We check if the line contains a fwd declaration of an enum
2133 if (enumPos != std::string::npos) {
2134 // We clear the scopes which we may have carried from a previous iteration
2135 scopes.clear();
2136 // We check if the enum is not in a scope. If yes, save its name
2137 // and the names of the enclosing scopes.
2138 if (enumPos != 0) {
2139 // it's enclosed in namespaces. We need to understand what they are
2140 auto nsPos = fwdDeclsLine.find("namespace");
2141 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2142 while (nsPos < enumPos && nsPos != std::string::npos) {
2143 // we have a namespace, let's put it in the collection of scopes
2144 const auto nsNameStart = nsPos + 10;
2145 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2146 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2147 scopes.push_back(nsName);
2148 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2149 }
2150 }
2151 clang::DeclContext* DC = 0;
2152 for (auto &&aScope: scopes) {
2153 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2154 if (!DC) {
2155 // No decl context means we have to fwd declare the enum.
2156 break;
2157 }
2158 }
2159 if (scopes.empty() || DC) {
2160 // We know the scope; let's look for the enum.
2161 size_t posEnumName = fwdDeclsLine.find("\"))) ", 32);
2162 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2163 posEnumName += 5; // skip "\"))) "
2164 while (isspace(fwdDeclsLine[posEnumName]))
2165 ++posEnumName;
2166 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2167 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2168 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2169 --posEnumNameEnd;
2170 // posEnumNameEnd now points to the last character of the name.
2171
2172 std::string enumName = fwdDeclsLine.substr(posEnumName,
2173 posEnumNameEnd - posEnumName + 1);
2174
2175 if (clang::NamedDecl* enumDecl
2176 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2177 enumName.c_str(), DC)) {
2178 // We have an existing enum decl (forward or definition);
2179 // skip this.
2180 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2181 (void)enumDecl;
2182 continue;
2183 }
2184 }
2185 }
2186
2187 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2188 }
2189 }
2190
2191 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2192 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2193 assert(cling::Interpreter::kSuccess == compRes &&
2194 "The forward declarations could not be compiled");
2195 if (compRes!=cling::Interpreter::kSuccess){
2196 Warning("TCling::RegisterModule",
2197 "Problems in compiling forward declarations for module %s: '%s'",
2198 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2199 }
2200 else if (T){
2201 // Loop over all decls in the transaction and go through them all
2202 // to mark them properly.
2203 // In order to do that, we first iterate over all the DelayedCallInfos
2204 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2205 // contained in the DelayedCallInfos. For each decl, we traverse.
2206 ExtLexicalStorageAdder elsa;
2207 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2208 cling::Transaction::DelayCallInfo& dci = *dciIt;
2209 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2210 clang::Decl* declPtr = *dit;
2211 elsa.TraverseDecl(declPtr);
2212 }
2213 }
2214 }
2215 }
2216
2217 // Now we register all the headers necessary for the class
2218 // Typical format of the array:
2219 // {"A", "classes.h", "@",
2220 // "vector<A>", "vector", "@",
2221 // "myClass", payloadCode, "@",
2222 // nullptr};
2223
2224 std::string temp;
2225 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2226 temp=*classesHeader;
2227
2228 size_t theTemplateHash = 0;
2229 bool addTemplate = false;
2230 size_t posTemplate = temp.find('<');
2231 if (posTemplate != std::string::npos) {
2232 // Add an entry for the template itself.
2233 std::string templateName = temp.substr(0, posTemplate);
2234 theTemplateHash = fStringHashFunction(templateName);
2235 addTemplate = true;
2236 }
2237 size_t theHash = fStringHashFunction(temp);
2238 classesHeader++;
2239 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2240 // This is done in order to distinguish headers from files and from the payloadCode
2241 if (payloadCode == *classesHeader_inner ){
2242 fPayloads.insert(theHash);
2243 if (addTemplate) fPayloads.insert(theTemplateHash);
2244 }
2245 if (gDebug > 2)
2246 Info("TCling::RegisterModule",
2247 "Adding a header for %s", temp.c_str());
2248 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2249 if (addTemplate) {
2250 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2251 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2252 }
2253 addTemplate = false;
2254 }
2255 }
2256 }
2257 }
2258
2259 clang::Sema &TheSema = fInterpreter->getSema();
2260
2261 bool ModuleWasSuccessfullyLoaded = false;
2262 if (hasCxxModule) {
2263 std::string ModuleName = modulename;
2264 if (llvm::StringRef(modulename).startswith("lib"))
2265 ModuleName = llvm::StringRef(modulename).substr(3).str();
2266
2267 // In case we are directly loading the library via gSystem->Load() without
2268 // specifying the relevant include paths we should try loading the
2269 // modulemap next to the library location.
2270 clang::Preprocessor &PP = TheSema.getPreprocessor();
2271 std::string ModuleMapName;
2272 if (isACLiC)
2273 ModuleMapName = ModuleName + ".modulemap";
2274 else
2275 ModuleMapName = "module.modulemap";
2276 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName),
2277 ModuleMapName);
2278
2279 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2280 // modules such as GenVector32 because it needs to fall back to GenVector.
2281 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2282 if (!ModuleWasSuccessfullyLoaded) {
2283 // Only report if we found the module in the modulemap.
2284 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2285 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2286 if (moduleMap.findModule(ModuleName))
2287 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2288 }
2289 }
2290
2291 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2292 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2293 // The path dyLibName might not be absolute. This can happen if dyLibName
2294 // is linked to an executable in the same folder.
2295 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2296 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2297 llvm::sys::path::append(pcmFileNameFullPath,
2299 LoadPCM(pcmFileNameFullPath.str().str());
2300 }
2301
2302 { // scope within which diagnostics are de-activated
2303 // For now we disable diagnostics because we saw them already at
2304 // dictionary generation time. That won't be an issue with the PCMs.
2305
2306 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2307
2308#if defined(R__MUST_REVISIT)
2309#if R__MUST_REVISIT(6,2)
2310 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2311#endif
2312#endif
2313
2314 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2315 SuspendAutoParsing autoParseRaii(this);
2316
2317 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2318 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2319 if (isACLiC) {
2320 // Register an unload point.
2321 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2322 }
2323
2324 assert(cling::Interpreter::kSuccess == compRes &&
2325 "Payload code of a dictionary could not be parsed correctly.");
2326 if (compRes!=cling::Interpreter::kSuccess) {
2327 Warning("TCling::RegisterModule",
2328 "Problems declaring payload for module %s.", modulename) ;
2329 }
2330 }
2331 }
2332
2333 // Now that all the header have been registered/compiled, let's
2334 // make sure to 'reset' the TClass that have a class init in this module
2335 // but already had their type information available (using information/header
2336 // loaded from other modules or from class rules or from opening a TFile
2337 // or from loading header in a way that did not provoke the loading of
2338 // the library we just loaded).
2340
2341 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2342 // __ROOTCLING__ might be pulled in through PCH
2343 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2344 "#undef __ROOTCLING__\n"
2345 + gInterpreterClassDef +
2346 "#endif");
2347 }
2348
2349 if (wasDlopened) {
2350 assert(isSharedLib);
2351 void* dyLibHandle = fRegisterModuleDyLibs.back();
2352 fRegisterModuleDyLibs.pop_back();
2353 dlclose(dyLibHandle);
2354 }
2355}
2356
2358 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2359 ASTContext &C = CI.getASTContext();
2360
2361 // Do not do anything if we have no global module index.
2362 // FIXME: This is mostly to real with false positives in the TTabCom
2363 // interface for non-modules.
2364 if (!fCxxModulesEnabled)
2365 return;
2366
2367 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2368 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2369 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2370 std::string I = Ident.str();
2371 if (!Idents.Contains(I.data()))
2372 Idents.Add(new TObjString(I.c_str()));
2373 }
2374 }
2375}
2376
2377
2378////////////////////////////////////////////////////////////////////////////////
2379/// Register classes that already existed prior to their dictionary loading
2380/// and that already had a ClassInfo (and thus would not be refresh via
2381/// UpdateClassInfo.
2382
2384{
2385 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2386}
2387
2388////////////////////////////////////////////////////////////////////////////////
2389/// If the dictionary is loaded, we can remove the class from the list
2390/// (otherwise the class might be loaded twice).
2391
2393{
2394 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2395 iterator stop = fClassesToUpdate.end();
2396 for(iterator i = fClassesToUpdate.begin();
2397 i != stop;
2398 ++i)
2399 {
2400 if ( i->first == oldcl ) {
2401 fClassesToUpdate.erase(i);
2402 return;
2403 }
2404 }
2405}
2406
2407
2408////////////////////////////////////////////////////////////////////////////////
2409/// Let cling process a command line.
2410///
2411/// If the command is executed and the error is 0, then the return value
2412/// is the int value corresponding to the result of the executed command
2413/// (float and double return values will be truncated).
2414///
2415
2416// Method for handling the interpreter exceptions.
2417// the MetaProcessor is passing in as argument to teh function, because
2418// cling::Interpreter::CompilationResult is a nested class and it cannot be
2419// forward declared, thus this method cannot be a static member function
2420// of TCling.
2421
2422static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2423 const char* input_line,
2424 cling::Interpreter::CompilationResult& compRes,
2425 cling::Value* result)
2426{
2427 try {
2428 return metaProcessor->process(input_line, compRes, result);
2429 }
2430 catch (cling::InterpreterException& ex)
2431 {
2432 Error("HandleInterpreterException", "%s.\n%s", ex.what(), "Execution of your code was aborted.");
2433 ex.diagnose();
2434 compRes = cling::Interpreter::kFailure;
2435 }
2436 return 0;
2437}
2438
2439////////////////////////////////////////////////////////////////////////////////
2440
2441bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2442{
2443 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2444 ie->diagnose();
2445 return true;
2446 }
2447 return false;
2448}
2449
2450////////////////////////////////////////////////////////////////////////////////
2451
2452Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
2453{
2454 // Copy the passed line, it comes from a static buffer in TApplication
2455 // which can be reentered through the Cling evaluation routines,
2456 // which would overwrite the static buffer and we would forget what we
2457 // were doing.
2458 //
2459 TString sLine(line);
2460 if (strstr(line,fantomline)) {
2461 // End-Of-Line action
2462 // See the comment (copied from above):
2463 // It is a "fantom" method to synchronize user keyboard input
2464 // and ROOT prompt line (for WIN32)
2465 // and is implemented by
2466 if (gApplication) {
2467 if (gApplication->IsCmdThread()) {
2469 gROOT->SetLineIsProcessing();
2470
2472
2473 gROOT->SetLineHasBeenProcessed();
2474 }
2475 }
2476 return 0;
2477 }
2478
2480 gGlobalMutex->Lock();
2481 if (!gInterpreterMutex)
2484 }
2486 gROOT->SetLineIsProcessing();
2487
2488 struct InterpreterFlagsRAII {
2489 cling::Interpreter* fInterpreter;
2490 bool fWasDynamicLookupEnabled;
2491
2492 InterpreterFlagsRAII(cling::Interpreter* interp):
2493 fInterpreter(interp),
2494 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2495 {
2496 fInterpreter->enableDynamicLookup(true);
2497 }
2498 ~InterpreterFlagsRAII() {
2499 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2500 gROOT->SetLineHasBeenProcessed();
2501 }
2502 } interpreterFlagsRAII(GetInterpreterImpl());
2503
2504 // A non-zero returned value means the given line was
2505 // not a complete statement.
2506 int indent = 0;
2507 // This will hold the resulting value of the evaluation the given line.
2508 cling::Value result;
2509 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2510 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2511 !strncmp(sLine.Data(), ".X", 2)) {
2512 // If there was a trailing "+", then CINT compiled the code above,
2513 // and we will need to strip the "+" before passing the line to cling.
2514 TString mod_line(sLine);
2515 TString aclicMode;
2516 TString arguments;
2517 TString io;
2518 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2519 aclicMode, arguments, io);
2520 if (aclicMode.Length()) {
2521 // Remove the leading '+'
2522 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2523 aclicMode[0]='k'; // We always want to keep the .so around.
2524 if (aclicMode[1]=='+') {
2525 // We have a 2nd +
2526 aclicMode[1]='f'; // We want to force the recompilation.
2527 }
2528 if (!gSystem->CompileMacro(fname,aclicMode)) {
2529 // ACLiC failed.
2530 compRes = cling::Interpreter::kFailure;
2531 } else {
2532 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2533 // if execution was requested.
2534
2535 if (arguments.Length()==0) {
2536 arguments = "()";
2537 }
2538 // We need to remove the extension.
2539 Ssiz_t ext = fname.Last('.');
2540 if (ext != kNPOS) {
2541 fname.Remove(ext);
2542 }
2543 const char *function = gSystem->BaseName(fname);
2544 mod_line = function + arguments + io;
2545 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2546 }
2547 }
2548 } else {
2549 // not ACLiC
2550 size_t unnamedMacroOpenCurly;
2551 {
2552 std::string code;
2553 std::string codeline;
2554 // Windows requires std::ifstream::binary to properly handle
2555 // CRLF and LF line endings
2556 std::ifstream in(fname, std::ifstream::binary);
2557 while (in) {
2558 std::getline(in, codeline);
2559 code += codeline + "\n";
2560 }
2561 unnamedMacroOpenCurly
2562 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2563 }
2564
2565 fCurExecutingMacros.push_back(fname);
2566 if (unnamedMacroOpenCurly != std::string::npos) {
2567 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2568 unnamedMacroOpenCurly);
2569 } else {
2570 // No DynLookup for .x, .L of named macros.
2571 fInterpreter->enableDynamicLookup(false);
2572 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2573 }
2574 fCurExecutingMacros.pop_back();
2575 }
2576 } // .L / .X / .x
2577 else {
2578 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2579 // explicitly ignore .autodict without having to support it
2580 // in cling.
2581
2582 // Turn off autoparsing if this is an include directive
2583 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2584 if (isInclusionDirective) {
2585 SuspendAutoParsing autoParseRaii(this);
2586 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2587 } else {
2588 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2589 }
2590 }
2591 }
2592 if (result.isValid())
2593 RegisterTemporary(result);
2594 if (indent) {
2595 if (error)
2596 *error = kProcessing;
2597 return 0;
2598 }
2599 if (error) {
2600 switch (compRes) {
2601 case cling::Interpreter::kSuccess: *error = kNoError; break;
2602 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2603 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2604 }
2605 }
2606 if (compRes == cling::Interpreter::kSuccess
2607 && result.isValid()
2608 && !result.isVoid())
2609 {
2610 return result.simplisticCastAs<long>();
2611 }
2612 return 0;
2613}
2614
2615////////////////////////////////////////////////////////////////////////////////
2616/// No-op; see TRint instead.
2617
2619{
2620}
2621
2622////////////////////////////////////////////////////////////////////////////////
2623/// \brief Add a directory to the list of directories in which the
2624/// interpreter looks for include files.
2625/// \param[in] path The path to the directory.
2626/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2627/// \b NOT supported.
2628/// \warning Only the path to the directory should be specified, without
2629/// prepending the \c -I prefix, i.e.
2630/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2631/// \c -I prefix is used it will be ignored.
2632void TCling::AddIncludePath(const char *path)
2633{
2635 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2636 // gCling->AddIncludePath() does not! Work around that inconsistency:
2637 if (path[0] == '-' && path[1] == 'I')
2638 path += 2;
2639 TString sPath(path);
2640 gSystem->ExpandPathName(sPath);
2641 fInterpreter->AddIncludePath(sPath.Data());
2642}
2643
2644////////////////////////////////////////////////////////////////////////////////
2645/// Visit all members over members, recursing over base classes.
2646
2647void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2648 const TClass* cl, Bool_t isTransient)
2649{
2653 }
2654
2655 if (!cl || cl->GetCollectionProxy()) {
2656 // We do not need to investigate the content of the STL
2657 // collection, they are opaque to us (and details are
2658 // uninteresting).
2659 return;
2660 }
2661
2662 static const TClassRef clRefString("std::string");
2663 if (clRefString == cl) {
2664 // We stream std::string without going through members..
2665 return;
2666 }
2667
2668 if (TClassEdit::IsStdArray(cl->GetName())) {
2669 // We treat std arrays as C arrays
2670 return;
2671 }
2672
2673 const char* cobj = (const char*) obj; // for ptr arithmetics
2674
2675 // Treat the case of std::complex in a special manner. We want to enforce
2676 // the layout of a stl implementation independent class, which is the
2677 // complex as implemented in ROOT5.
2678
2679 // A simple lambda to simplify the code
2680 auto inspInspect = [&] (ptrdiff_t offset){
2681 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2682 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2683 };
2684
2685 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2686 switch(complexType) {
2688 {
2689 break;
2690 }
2692 {
2693 inspInspect(sizeof(float));
2694 return;
2695 }
2697 {
2698 inspInspect(sizeof(double));
2699 return;
2700 }
2702 {
2703 inspInspect(sizeof(int));
2704 return;
2705 }
2707 {
2708 inspInspect(sizeof(long));
2709 return;
2710 }
2711 }
2712
2713 static clang::PrintingPolicy
2714 printPol(fInterpreter->getCI()->getLangOpts());
2715 if (printPol.Indentation) {
2716 // not yet initialized
2717 printPol.Indentation = 0;
2718 printPol.SuppressInitializers = true;
2719 }
2720
2721 const char* clname = cl->GetName();
2722 // Printf("Inspecting class %s\n", clname);
2723
2724 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2725 const clang::Decl *scopeDecl = 0;
2726 const clang::Type *recordType = 0;
2727
2728 if (cl->GetClassInfo()) {
2729 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2730 scopeDecl = clingCI->GetDecl();
2731 recordType = clingCI->GetType();
2732 } else {
2733 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2734 // Diags will complain about private classes:
2735 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2736 &recordType);
2737 }
2738 if (!scopeDecl) {
2739 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2740 return;
2741 }
2742 const clang::CXXRecordDecl* recordDecl
2743 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2744 if (!recordDecl) {
2745 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2746 return;
2747 }
2748
2749 {
2750 // Force possible deserializations first. We need to have no pending
2751 // Transaction when passing control flow to the inspector below (ROOT-7779).
2752 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2753
2754 astContext.getASTRecordLayout(recordDecl);
2755
2756 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2757 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2758 }
2759
2760 const clang::ASTRecordLayout& recLayout
2761 = astContext.getASTRecordLayout(recordDecl);
2762
2763 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2764 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2765 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2766 // cl->GetName());
2767 // }
2768 if (cl->Size() != recLayout.getSize().getQuantity()) {
2769 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2770 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2771 }
2772
2773 unsigned iNField = 0;
2774 // iterate over fields
2775 // FieldDecls are non-static, else it would be a VarDecl.
2776 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2777 eField = recordDecl->field_end(); iField != eField;
2778 ++iField, ++iNField) {
2779
2780
2781 clang::QualType memberQT = iField->getType();
2782 if (recordType) {
2783 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2784 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2785 }
2786 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2787 if (memberQT.isNull()) {
2788 std::string memberName;
2789 llvm::raw_string_ostream stream(memberName);
2790 // Don't trigger fopen of the source file to count lines:
2791 printPol.AnonymousTagLocations = false;
2792 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2793 stream.flush();
2794 Error("InspectMembers",
2795 "Cannot retrieve QualType for member %s while inspecting class %s",
2796 memberName.c_str(), clname);
2797 continue; // skip member
2798 }
2799 const clang::Type* memType = memberQT.getTypePtr();
2800 if (!memType) {
2801 std::string memberName;
2802 llvm::raw_string_ostream stream(memberName);
2803 // Don't trigger fopen of the source file to count lines:
2804 printPol.AnonymousTagLocations = false;
2805 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2806 stream.flush();
2807 Error("InspectMembers",
2808 "Cannot retrieve Type for member %s while inspecting class %s",
2809 memberName.c_str(), clname);
2810 continue; // skip member
2811 }
2812
2813 const clang::Type* memNonPtrType = memType;
2814 Bool_t ispointer = false;
2815 if (memNonPtrType->isPointerType()) {
2816 ispointer = true;
2817 clang::QualType ptrQT
2818 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2819 if (recordType) {
2820 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2821 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2822 }
2823 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2824 if (ptrQT.isNull()) {
2825 std::string memberName;
2826 llvm::raw_string_ostream stream(memberName);
2827 // Don't trigger fopen of the source file to count lines:
2828 printPol.AnonymousTagLocations = false;
2829 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2830 stream.flush();
2831 Error("InspectMembers",
2832 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2833 memberName.c_str(), clname);
2834 continue; // skip member
2835 }
2836 memNonPtrType = ptrQT.getTypePtr();
2837 }
2838
2839 // assemble array size(s): "[12][4][]"
2840 llvm::SmallString<8> arraySize;
2841 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2842 unsigned arrLevel = 0;
2843 bool haveErrorDueToArray = false;
2844 while (arrType) {
2845 ++arrLevel;
2846 arraySize += '[';
2847 const clang::ConstantArrayType* constArrType =
2848 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2849 if (constArrType) {
2850 constArrType->getSize().toStringUnsigned(arraySize);
2851 }
2852 arraySize += ']';
2853 clang::QualType subArrQT = arrType->getElementType();
2854 if (subArrQT.isNull()) {
2855 std::string memberName;
2856 llvm::raw_string_ostream stream(memberName);
2857 // Don't trigger fopen of the source file to count lines:
2858 printPol.AnonymousTagLocations = false;
2859 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2860 stream.flush();
2861 Error("InspectMembers",
2862 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2863 arrLevel, subArrQT.getAsString(printPol).c_str(),
2864 memberName.c_str(), clname);
2865 haveErrorDueToArray = true;
2866 break;
2867 }
2868 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2869 }
2870 if (haveErrorDueToArray) {
2871 continue; // skip member
2872 }
2873
2874 // construct member name
2875 std::string fieldName;
2876 if (memType->isPointerType()) {
2877 fieldName = "*";
2878 }
2879
2880 // Check if this field has a custom ioname, if not, just use the one of the decl
2881 std::string ioname(iField->getName());
2882 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2883 fieldName += ioname;
2884 fieldName += arraySize;
2885
2886 // get member offset
2887 // NOTE currently we do not support bitfield and do not support
2888 // member that are not aligned on 'bit' boundaries.
2889 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2890 ptrdiff_t fieldOffset = offset.getQuantity();
2891
2892 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2893 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2894 // R__insp.InspectMember(fName, "fName.");
2895 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2896
2897 // If the class has a custom streamer and the type of the filed is a
2898 // private enum, struct or class, skip it.
2899 if (!insp.IsTreatingNonAccessibleTypes()){
2900 auto iFiledQtype = iField->getType();
2901 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2902 auto declAccess = tagDecl->getAccess();
2903 if (declAccess == AS_private || declAccess == AS_protected) {
2904 continue;
2905 }
2906 }
2907 }
2908
2909 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2910
2911 if (!ispointer) {
2912 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2913 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2914 // nested objects get an extra call to InspectMember
2915 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2916 std::string sFieldRecName;
2917 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2919 clang::QualType(memNonPtrType,0),
2920 *fInterpreter,
2922 }
2923
2924 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2925 // if we can not find the member (which should not really happen),
2926 // let's consider it transient.
2927 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2928
2929 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2930 (fieldName + '.').c_str(), transient);
2931
2932 }
2933 }
2934 } // loop over fields
2935
2936 // inspect bases
2937 // TNamed::ShowMembers(R__insp);
2938 unsigned iNBase = 0;
2939 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2940 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2941 iBase != eBase; ++iBase, ++iNBase) {
2942 clang::QualType baseQT = iBase->getType();
2943 if (baseQT.isNull()) {
2944 Error("InspectMembers",
2945 "Cannot find QualType for base number %d while inspecting class %s",
2946 iNBase, clname);
2947 continue;
2948 }
2949 const clang::CXXRecordDecl* baseDecl
2950 = baseQT->getAsCXXRecordDecl();
2951 if (!baseDecl) {
2952 Error("InspectMembers",
2953 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2954 iNBase, clname);
2955 continue;
2956 }
2957 TClass* baseCl=nullptr;
2958 std::string sBaseName;
2959 // Try with the DeclId
2960 std::vector<TClass*> foundClasses;
2961 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2962 if (foundClasses.size()==1){
2963 baseCl=foundClasses[0];
2964 } else {
2965 // Try with the normalised Name, as a fallback
2966 if (!baseCl){
2968 baseQT,
2969 *fInterpreter,
2971 baseCl = TClass::GetClass(sBaseName.c_str());
2972 }
2973 }
2974
2975 if (!baseCl){
2976 std::string qualNameForDiag;
2977 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2978 Error("InspectMembers",
2979 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2980 continue;
2981 }
2982
2983 int64_t baseOffset;
2984 if (iBase->isVirtual()) {
2986 if (!isTransient) {
2987 Error("InspectMembers",
2988 "Base %s of class %s is virtual but no object provided",
2989 sBaseName.c_str(), clname);
2990 }
2992 } else {
2993 // We have an object to determine the vbase offset.
2995 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
2996 if (ci && baseCi) {
2997 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
2998 true /*isDerivedObj*/);
2999 if (baseOffset == -1) {
3000 Error("InspectMembers",
3001 "Error calculating offset of virtual base %s of class %s",
3002 sBaseName.c_str(), clname);
3003 }
3004 } else {
3005 Error("InspectMembers",
3006 "Cannot calculate offset of virtual base %s of class %s",
3007 sBaseName.c_str(), clname);
3008 continue;
3009 }
3010 }
3011 } else {
3012 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3013 }
3014 // TOFIX: baseCl can be null here!
3015 if (baseCl->IsLoaded()) {
3016 // For loaded class, CallShowMember will (especially for TObject)
3017 // call the virtual ShowMember rather than the class specific version
3018 // resulting in an infinite recursion.
3019 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3020 } else {
3021 baseCl->CallShowMembers(cobj + baseOffset,
3022 insp, isTransient);
3023 }
3024 } // loop over bases
3025}
3026
3027////////////////////////////////////////////////////////////////////////////////
3028/// Reset the interpreter internal state in case a previous action was not correctly
3029/// terminated.
3030
3032{
3033 // No-op there is not equivalent state (to be cleared) in Cling.
3034}
3035
3036////////////////////////////////////////////////////////////////////////////////
3037/// Delete existing temporary values.
3038
3040{
3041 // No-op for cling due to cling::Value.
3042}
3043
3044////////////////////////////////////////////////////////////////////////////////
3045/// Declare code to the interpreter, without any of the interpreter actions
3046/// that could trigger a re-interpretation of the code. I.e. make cling
3047/// behave like a compiler: no dynamic lookup, no input wrapping for
3048/// subsequent execution, no automatic provision of declarations but just a
3049/// plain #include.
3050/// Returns true on success, false on failure.
3051
3052bool TCling::Declare(const char* code)
3053{
3055
3056 SuspendAutoLoadingRAII autoLoadOff(this);
3057 SuspendAutoParsing autoParseRaii(this);
3058
3059 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3060 fInterpreter->enableDynamicLookup(false);
3061 bool oldRawInput = fInterpreter->isRawInputEnabled();
3062 fInterpreter->enableRawInput(true);
3063
3064 Bool_t ret = LoadText(code);
3065
3066 fInterpreter->enableRawInput(oldRawInput);
3067 fInterpreter->enableDynamicLookup(oldDynLookup);
3068 return ret;
3069}
3070
3071////////////////////////////////////////////////////////////////////////////////
3072/// It calls a "fantom" method to synchronize user keyboard input
3073/// and ROOT prompt line.
3074
3076{
3078}
3079
3080// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3081// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3082// was already taking a lock.
3083static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3084{
3085 // Check shared library.
3086 TString tLibName(libname);
3087 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3088 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3089 return false;
3090}
3091
3092Bool_t TCling::IsLibraryLoaded(const char* libname) const
3093{
3095 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3096}
3097
3098////////////////////////////////////////////////////////////////////////////////
3099/// Return true if ROOT has cxxmodules pcm for a given library name.
3100// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3101Bool_t TCling::HasPCMForLibrary(const char *libname) const
3102{
3103 llvm::StringRef ModuleName(libname);
3104 ModuleName = llvm::sys::path::stem(ModuleName);
3105 ModuleName.consume_front("lib");
3106
3107 // FIXME: In case when the modulemap is not yet loaded we will return the
3108 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3109 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3110 // which may happen after calling this interface. Maybe we should also check
3111 // if there is a Event.pcm file and a module.modulemap, load it and return
3112 // true.
3113 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3114 clang::Module *M = moduleMap.findModule(ModuleName);
3115 return M && !M->IsMissingRequirement && M->getASTFile();
3116}
3117
3118////////////////////////////////////////////////////////////////////////////////
3119/// Return true if the file has already been loaded by cint.
3120/// We will try in this order:
3121/// actual filename
3122/// filename as a path relative to
3123/// the include path
3124/// the shared library path
3125
3126Bool_t TCling::IsLoaded(const char* filename) const
3127{
3129
3130 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3131 // cling::DynamicLibraryManager.
3132
3133 std::string file_name = filename;
3134 size_t at = std::string::npos;
3135 while ((at = file_name.find("/./")) != std::string::npos)
3136 file_name.replace(at, 3, "/");
3137
3138 std::string filesStr = "";
3139 llvm::raw_string_ostream filesOS(filesStr);
3140 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3141 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3142 filesOS.flush();
3143
3144 llvm::SmallVector<llvm::StringRef, 100> files;
3145 llvm::StringRef(filesStr).split(files, "\n");
3146
3147 std::set<std::string> fileMap;
3148 // Fill fileMap; return early on exact match.
3149 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3150 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3151 if ((*iF) == file_name.c_str()) return kTRUE; // exact match
3152 fileMap.insert(*iF);
3153 }
3154
3155 if (fileMap.empty()) return kFALSE;
3156
3157 // Check MacroPath.
3158 TString sFilename(file_name.c_str());
3160 && fileMap.count(sFilename.Data())) {
3161 return kTRUE;
3162 }
3163
3164 // Check IncludePath.
3165 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3166 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3167 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3168 while (incPath.Index(" :") != -1) {
3169 incPath.ReplaceAll(" :", ":");
3170 }
3171 incPath.Prepend(".:");
3172 sFilename = file_name.c_str();
3173 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3174 && fileMap.count(sFilename.Data())) {
3175 return kTRUE;
3176 }
3177
3178 // Check shared library.
3179 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3180 return kTRUE;
3181
3182 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3183 const clang::DirectoryLookup *CurDir = 0;
3184 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3185 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3186 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
3187 clang::SourceLocation(),
3188 /*isAngled*/ false,
3189 /*FromDir*/ 0, CurDir,
3190 clang::ArrayRef<std::pair<const clang::FileEntry *,
3191 const clang::DirectoryEntry *>>(),
3192 /*SearchPath*/ 0,
3193 /*RelativePath*/ 0,
3194 /*RequestingModule*/ 0,
3195 /*SuggestedModule*/ 0,
3196 /*IsMapped*/ 0,
3197 /*IsFrameworkFound*/ nullptr,
3198 /*SkipCache*/ false,
3199 /*BuildSystemModule*/ false,
3200 /*OpenFile*/ false,
3201 /*CacheFail*/ false);
3202 if (FE && FE->isValid()) {
3203 // check in the source manager if the file is actually loaded
3204 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3205 // this works only with header (and source) files...
3206 clang::FileID FID = SM.translateFile(FE);
3207 if (!FID.isInvalid() && FID.getHashValue() == 0)
3208 return kFALSE;
3209 else {
3210 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3211 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
3212 return kFALSE;
3213 if (!FID.isInvalid())
3214 return kTRUE;
3215 }
3216 // ...then check shared library again, but with full path now
3217 sFilename = FE->getName();
3218 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3219 && fileMap.count(sFilename.Data())) {
3220 return kTRUE;
3221 }
3222 }
3223 return kFALSE;
3224}
3225
3226
3227#if defined(R__MACOSX)
3228
3229////////////////////////////////////////////////////////////////////////////////
3230/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3231/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3232/// to `-lFOO` such that it can be passed to the linker.
3233/// This is a unique feature of macOS 11.
3234
3235static bool R__UpdateLibFileForLinking(TString &lib)
3236{
3237 const char *mapfile = nullptr;
3238#if __x86_64__
3239 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3240#elif __arm64__
3241 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3242#else
3243 #error unsupported architecture
3244#endif
3245 if (std::ifstream cacheMap{mapfile}) {
3246 std::string line;
3247 while (getline(cacheMap, line)) {
3248 if (line.find(lib) != std::string::npos) {
3249 lib.ReplaceAll("/usr/lib/lib","-l");
3250 lib.ReplaceAll(".dylib","");
3251 return true;
3252 }
3253 }
3254 return false;
3255 }
3256 return false;
3257}
3258#endif // R__MACOSX
3259
3260#ifdef R__LINUX
3261
3262////////////////////////////////////////////////////////////////////////////////
3263/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3264/// Collects opened libraries.
3265
3266static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3267{
3268 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3269 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3270
3271 auto newLibs = static_cast<std::vector<std::string>*>(data);
3272 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3273 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3274 if (info->dlpi_name && info->dlpi_name[0]
3275 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3276 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3277 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3278 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3279 newLibs->emplace_back(info->dlpi_name);
3280 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3281 }
3282 // No matter what the doc says, return != 0 means "stop the iteration".
3283 return 0;
3284}
3285
3286#endif // R__LINUX
3287
3288
3289////////////////////////////////////////////////////////////////////////////////
3290
3292{
3293#if defined(R__WIN32) || defined(__CYGWIN__)
3294 HMODULE hModules[1024];
3295 void *hProcess;
3296 unsigned long cbModules;
3297 unsigned int i;
3298 hProcess = (void *)::GetCurrentProcess();
3299 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3300 // start at 1 to skip the executable itself
3301 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3302 static const int bufsize = 260;
3303 wchar_t winname[bufsize];
3304 char posixname[bufsize];
3305 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3306#if defined(__CYGWIN__)
3307 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3308#else
3309 std::wstring wpath = winname;
3310 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3311 string path(wpath.begin(), wpath.end());
3312 strncpy(posixname, path.c_str(), bufsize);
3313#endif
3314 if (!fSharedLibs.Contains(posixname)) {
3315 RegisterLoadedSharedLibrary(posixname);
3316 }
3317 }
3318#elif defined(R__MACOSX)
3319 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3320 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3321
3322 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3323 // Skip non-dylibs
3324 if (mh->filetype == MH_DYLIB) {
3325 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3326 RegisterLoadedSharedLibrary(imageName);
3327 }
3328 }
3329
3330 ++imageIndex;
3331 }
3332 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3333#elif defined(R__LINUX)
3334 // fPrevLoadedDynLibInfo is unused on Linux.
3336
3337 std::vector<std::string> newLibs;
3338 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3339 for (auto &&lib: newLibs)
3340 RegisterLoadedSharedLibrary(lib.c_str());
3341#else
3342 Error("TCling::UpdateListOfLoadedSharedLibraries",
3343 "Platform not supported!");
3344#endif
3345}
3346
3347////////////////////////////////////////////////////////////////////////////////
3348/// Register a new shared library name with the interpreter; add it to
3349/// fSharedLibs.
3350
3351void TCling::RegisterLoadedSharedLibrary(const char* filename)
3352{
3353 // Ignore NULL filenames, aka "the process".
3354 if (!filename) return;
3355
3356 // Tell the interpreter that this library is available; all libraries can be
3357 // used to resolve symbols.
3358 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3359 if (!DLM->isLibraryLoaded(filename)) {
3360 DLM->loadLibrary(filename, true /*permanent*/);
3361 }
3362
3363#if defined(R__MACOSX)
3364 // Check that this is not a system library
3365 auto lenFilename = strlen(filename);
3366 if (!strncmp(filename, "/usr/lib/system/", 16)
3367 || !strncmp(filename, "/usr/lib/libc++", 15)
3368 || !strncmp(filename, "/System/Library/Frameworks/", 27)
3369 || !strncmp(filename, "/System/Library/PrivateFrameworks/", 34)
3370 || !strncmp(filename, "/System/Library/CoreServices/", 29)
3371 || !strcmp(filename, "cl_kernels") // yepp, no directory
3372 || strstr(filename, "/usr/lib/libSystem")
3373 || strstr(filename, "/usr/lib/libstdc++")
3374 || strstr(filename, "/usr/lib/libicucore")
3375 || strstr(filename, "/usr/lib/libbsm")
3376 || strstr(filename, "/usr/lib/libobjc")
3377 || strstr(filename, "/usr/lib/libresolv")
3378 || strstr(filename, "/usr/lib/libauto")
3379 || strstr(filename, "/usr/lib/libcups")
3380 || strstr(filename, "/usr/lib/libDiagnosticMessagesClient")
3381 || strstr(filename, "/usr/lib/liblangid")
3382 || strstr(filename, "/usr/lib/libCRFSuite")
3383 || strstr(filename, "/usr/lib/libpam")
3384 || strstr(filename, "/usr/lib/libOpenScriptingUtil")
3385 || strstr(filename, "/usr/lib/libextension")
3386 || strstr(filename, "/usr/lib/libAudioToolboxUtility")
3387 || strstr(filename, "/usr/lib/liboah")
3388 || strstr(filename, "/usr/lib/libRosetta")
3389 || strstr(filename, "/usr/lib/libssl.")
3390 || strstr(filename, "/usr/lib/libcrypto.")
3391 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3392 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3393 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3394 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3395 return;
3396 TString sFileName(filename);
3397 R__UpdateLibFileForLinking(sFileName);
3398 filename = sFileName.Data();
3399#elif defined(__CYGWIN__)
3400 // Check that this is not a system library
3401 static const int bufsize = 260;
3402 char posixwindir[bufsize];
3403 char *windir = getenv("WINDIR");
3404 if (windir)
3405 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3406 else
3407 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3408 if (strstr(filename, posixwindir) ||
3409 strstr(filename, "/usr/bin/cyg"))
3410 return;
3411#elif defined(R__WIN32)
3412 if (strstr(filename, "/Windows/"))
3413 return;
3414#elif defined (R__LINUX)
3415 if (strstr(filename, "/ld-linux")
3416 || strstr(filename, "linux-gnu/")
3417 || strstr(filename, "/libstdc++.")
3418 || strstr(filename, "/libgcc")
3419 || strstr(filename, "/libc.")
3420 || strstr(filename, "/libdl.")
3421 || strstr(filename, "/libm."))
3422 return;
3423#endif
3424 // Update string of available libraries.
3425 if (!fSharedLibs.IsNull()) {
3426 fSharedLibs.Append(" ");
3427 }
3428 fSharedLibs.Append(filename);
3429}
3430
3431////////////////////////////////////////////////////////////////////////////////
3432/// Load a library file in cling's memory.
3433/// if 'system' is true, the library is never unloaded.
3434/// Return 0 on success, -1 on failure.
3435
3436Int_t TCling::Load(const char* filename, Bool_t system)
3437{
3438 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3439
3440 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3442 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3443 std::string canonLib = DLM->lookupLibrary(filename);
3444 cling::DynamicLibraryManager::LoadLibResult res
3445 = cling::DynamicLibraryManager::kLoadLibNotFound;
3446 if (!canonLib.empty()) {
3447 if (system)
3448 res = DLM->loadLibrary(filename, system);
3449 else {
3450 // For the non system libs, we'd like to be able to unload them.
3451 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3452 cling::Interpreter::CompilationResult compRes;
3453 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3454 if (compRes == cling::Interpreter::kSuccess)
3455 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3456 }
3457 }
3458
3459 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3461 }
3462 switch (res) {
3463 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3464 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3465 default: break;
3466 };
3467 return -1;
3468}
3469
3470////////////////////////////////////////////////////////////////////////////////
3471/// Load a macro file in cling's memory.
3472
3473void TCling::LoadMacro(const char* filename, EErrorCode* error)
3474{
3475 ProcessLine(Form(".L %s", filename), error);
3476}
3477
3478////////////////////////////////////////////////////////////////////////////////
3479/// Let cling process a command line asynch.
3480
3482{
3483 return ProcessLine(line, error);
3484}
3485
3486////////////////////////////////////////////////////////////////////////////////
3487/// Let cling process a command line synchronously, i.e we are waiting
3488/// it will be finished.
3489
3491{
3493 if (gApplication) {
3494 if (gApplication->IsCmdThread()) {
3495 return ProcessLine(line, error);
3496 }
3497 return 0;
3498 }
3499 return ProcessLine(line, error);
3500}
3501
3502////////////////////////////////////////////////////////////////////////////////
3503/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3504/// however not declarations, like "Int_t x;").
3505
3507{
3508#ifdef R__WIN32
3509 // Test on ApplicationImp not being 0 is needed because only at end of
3510 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3511 // we can not use it.
3513 while (gROOT->IsLineProcessing() && !gApplication) {
3514 Warning("Calc", "waiting for cling thread to free");
3515 gSystem->Sleep(500);
3516 }
3517 gROOT->SetLineIsProcessing();
3518 }
3519#endif // R__WIN32
3521 if (error) {
3522 *error = TInterpreter::kNoError;
3523 }
3524 cling::Value valRef;
3525 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3526 try {
3527 cr = fInterpreter->evaluate(line, valRef);
3528 }
3529 catch (cling::InterpreterException& ex)
3530 {
3531 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3532 ex.diagnose();
3533 cr = cling::Interpreter::kFailure;
3534 }
3535
3536 if (cr != cling::Interpreter::kSuccess) {
3537 // Failure in compilation.
3538 if (error) {
3539 // Note: Yes these codes are weird.
3541 }
3542 return 0L;
3543 }
3544 if (!valRef.isValid()) {
3545 // Failure at runtime.
3546 if (error) {
3547 // Note: Yes these codes are weird.
3548 *error = TInterpreter::kDangerous;
3549 }
3550 return 0L;
3551 }
3552
3553 if (valRef.isVoid()) {
3554 return 0;
3555 }
3556
3557 RegisterTemporary(valRef);
3558#ifdef R__WIN32
3560 gROOT->SetLineHasBeenProcessed();
3561 }
3562#endif // R__WIN32
3563 return valRef.simplisticCastAs<long>();
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Set a getline function to call when input is needed.
3568
3569void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3570 void (*histaddFunc)(const char* line))
3571{
3572 // If cling offers a replacement for G__pause(), it would need to
3573 // also offer a way to customize at least the history recording.
3574
3575#if defined(R__MUST_REVISIT)
3576#if R__MUST_REVISIT(6,2)
3577 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3578#endif
3579#endif
3580}
3581
3582////////////////////////////////////////////////////////////////////////////////
3583/// Helper function to increase the internal Cling count of transactions
3584/// that change the AST.
3585
3586Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3587{
3589
3590 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3591 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3592 || T.macros_begin() != T.macros_end()
3593 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3595 return true;
3596 }
3597 return false;
3598}
3599
3600////////////////////////////////////////////////////////////////////////////////
3601/// Delete object from cling symbol table so it can not be used anymore.
3602/// cling objects are always on the heap.
3603
3605{
3606 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3607 // put in place the Read/Write part here. Keeping the write lock
3608 // here is 'catasptrophic' for scaling as it means that ALL calls
3609 // to RecursiveRemove will take the write lock and performance
3610 // of many threads trying to access the write lock at the same
3611 // time is relatively bad.
3613 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3614 // (but isn't at the moment).
3615 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3616 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3617 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3619 DeleteGlobal(obj);
3620 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3621 }
3622 }
3623}
3624
3625////////////////////////////////////////////////////////////////////////////////
3626/// Pressing Ctrl+C should forward here. In the case where we have had
3627/// continuation requested we must reset it.
3628
3630{
3631 fMetaProcessor->cancelContinuation();
3632 // Reset the Cling state to the state saved by the last call to
3633 // TCling::SaveContext().
3634#if defined(R__MUST_REVISIT)
3635#if R__MUST_REVISIT(6,2)
3637 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3638#endif
3639#endif
3640}
3641
3642////////////////////////////////////////////////////////////////////////////////
3643/// Reset the Cling state to its initial state.
3644
3646{
3647#if defined(R__MUST_REVISIT)
3648#if R__MUST_REVISIT(6,2)
3650 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3651#endif
3652#endif
3653}
3654
3655////////////////////////////////////////////////////////////////////////////////
3656/// Reset in Cling the list of global variables to the state saved by the last
3657/// call to TCling::SaveGlobalsContext().
3658///
3659/// Note: Right now, all we do is run the global destructors.
3660
3662{
3664 // TODO:
3665 // Here we should iterate over the transactions (N-3) and revert.
3666 // N-3 because the first three internal to cling.
3667
3668 fInterpreter->runAndRemoveStaticDestructors();
3669}
3670
3671////////////////////////////////////////////////////////////////////////////////
3672/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3673/// call to TCling::SaveGlobalsContext().
3674
3676{
3677#if defined(R__MUST_REVISIT)
3678#if R__MUST_REVISIT(6,2)
3680 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3681#endif
3682#endif
3683}
3684
3685////////////////////////////////////////////////////////////////////////////////
3686/// Rewind Cling dictionary to the point where it was before executing
3687/// the current macro. This function is typically called after SEGV or
3688/// ctlr-C after doing a longjmp back to the prompt.
3689
3691{
3692#if defined(R__MUST_REVISIT)
3693#if R__MUST_REVISIT(6,2)
3695 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3696#endif
3697#endif
3698}
3699
3700////////////////////////////////////////////////////////////////////////////////
3701/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3702/// Returns 1 in case of success and 0 in case object was not in table.
3703
3705{
3706#if defined(R__MUST_REVISIT)
3707#if R__MUST_REVISIT(6,2)
3709 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3710#endif
3711#endif
3712 return 0;
3713}
3714
3715////////////////////////////////////////////////////////////////////////////////
3716/// Undeclare obj called name.
3717/// Returns 1 in case of success, 0 for failure.
3718
3720{
3721#if defined(R__MUST_REVISIT)
3722#if R__MUST_REVISIT(6,2)
3723 Warning("DeleteVariable","should do more that just reseting the value to zero");
3724#endif
3725#endif
3726
3728 llvm::StringRef srName(name);
3729 const char* unscopedName = name;
3730 llvm::StringRef::size_type posScope = srName.rfind("::");
3731 const clang::DeclContext* declCtx = 0;
3732 if (posScope != llvm::StringRef::npos) {
3733 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3734 const clang::Decl* scopeDecl
3735 = lh.findScope(srName.substr(0, posScope),
3736 cling::LookupHelper::WithDiagnostics);
3737 if (!scopeDecl) {
3738 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3739 name);
3740 return 0;
3741 }
3742 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3743 if (!declCtx) {
3744 Error("DeleteVariable",
3745 "Enclosing scope for variable %s is not a declaration context",
3746 name);
3747 return 0;
3748 }
3749 unscopedName += posScope + 2;
3750 }
3751 // Could trigger deserialization of decls.
3752 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3753 clang::NamedDecl* nVarDecl
3754 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3755 if (!nVarDecl) {
3756 Error("DeleteVariable", "Unknown variable %s", name);
3757 return 0;
3758 }
3759 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3760 if (!varDecl) {
3761 Error("DeleteVariable", "Entity %s is not a variable", name);
3762 return 0;
3763 }
3764
3765 clang::QualType qType = varDecl->getType();
3766 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3767 // Cannot set a reference's address to nullptr; the JIT can place it
3768 // into read-only memory (ROOT-7100).
3769 if (type->isPointerType()) {
3770 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3771 // set pointer to invalid.
3772 if (ppInt) *ppInt = 0;
3773 }
3774 return 1;
3775}
3776
3777////////////////////////////////////////////////////////////////////////////////
3778/// Save the current Cling state.
3779
3781{
3782#if defined(R__MUST_REVISIT)
3783#if R__MUST_REVISIT(6,2)
3785 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3786#endif
3787#endif
3788}
3789
3790////////////////////////////////////////////////////////////////////////////////
3791/// Save the current Cling state of global objects.
3792
3794{
3795#if defined(R__MUST_REVISIT)
3796#if R__MUST_REVISIT(6,2)
3798 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3799#endif
3800#endif
3801}
3802
3803////////////////////////////////////////////////////////////////////////////////
3804/// No op: see TClingCallbacks (used to update the list of globals)
3805
3807{
3808}
3809
3810////////////////////////////////////////////////////////////////////////////////
3811/// No op: see TClingCallbacks (used to update the list of global functions)
3812
3814{
3815}
3816
3817////////////////////////////////////////////////////////////////////////////////
3818/// No op: see TClingCallbacks (used to update the list of types)
3819
3821{
3822}
3823
3824////////////////////////////////////////////////////////////////////////////////
3825/// Check in what order the member of a tuple are layout.
3826enum class ETupleOrdering {
3827 kAscending,
3830};
3831
3832struct AlternateTupleIntDoubleAsc
3833{
3834 Int_t _0;
3835 Double_t _1;
3836};
3837
3838struct AlternateTupleIntDoubleDes
3839{
3840 Double_t _1;
3841 Int_t _0;
3842};
3843
3845{
3846 std::tuple<int,double> value;
3847 AlternateTupleIntDoubleAsc asc;
3848 AlternateTupleIntDoubleDes des;
3849
3850 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3851 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3852
3853 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3854 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3855
3856 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3857 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3858
3859 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3861 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3863 } else {
3865 }
3866}
3867
3868static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3869{
3870 TClassEdit::TSplitType tupleContent(classname);
3871 std::string alternateName = "TEmulatedTuple";
3872 alternateName.append( classname + 5 );
3873
3874 std::string fullname = "ROOT::Internal::" + alternateName;
3875 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3876 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3877 return fullname;
3878
3879 std::string guard_name;
3880 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3881 std::ostringstream guard;
3882 guard << "ROOT_INTERNAL_TEmulated_";
3883 guard << guard_name;
3884
3885 std::ostringstream alternateTuple;
3886 alternateTuple << "#ifndef " << guard.str() << "\n";
3887 alternateTuple << "#define " << guard.str() << "\n";
3888 alternateTuple << "namespace ROOT { namespace Internal {\n";
3889 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3890 alternateTuple << "template <> struct " << alternateName << " {\n";
3891
3892 // This could also be a compile time choice ...
3893 switch(IsTupleAscending()) {
3895 unsigned int nMember = 0;
3896 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3897 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3898 while (iter != theEnd) {
3899 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3900 ++iter;
3901 ++nMember;
3902 }
3903 break;
3904 }
3906 unsigned int nMember = tupleContent.fElements.size() - 3;
3907 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3908 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3909 while (iter != theEnd) {
3910 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3911 ++iter;
3912 --nMember;
3913 }
3914 break;
3915 }
3917 Fatal("TCling::SetClassInfo::AlternateTuple",
3918 "Layout of std::tuple on this platform is unexpected.");
3919 break;
3920 }
3921 }
3922
3923 alternateTuple << "};\n";
3924 alternateTuple << "}}\n";
3925 alternateTuple << "#endif\n";
3926 if (!gCling->Declare(alternateTuple.str().c_str())) {
3927 Error("Load","Could not declare %s",alternateName.c_str());
3928 return "";
3929 }
3930 alternateName = "ROOT::Internal::" + alternateName;
3931 return alternateName;
3932}
3933
3934////////////////////////////////////////////////////////////////////////////////
3935/// Set pointer to the TClingClassInfo in TClass.
3936/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3937/// already have one.
3938
3940{
3941 // We are shutting down, there is no point in reloading, it only triggers
3942 // redundant deserializations.
3943 if (fIsShuttingDown) {
3944 // Remove the decl_id from the DeclIdToTClass map
3945 if (cl->fClassInfo) {
3947 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3948 // Test again as another thread may have set fClassInfo to nullptr.
3949 if (TClinginfo) {
3950 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3951 }
3952 delete TClinginfo;
3953 cl->fClassInfo = nullptr;
3954 }
3955 return;
3956 }
3957
3959 if (cl->fClassInfo && !reload) {
3960 return;
3961 }
3962 //Remove the decl_id from the DeclIdToTClass map
3963 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3964 if (TClinginfo) {
3965 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3966 }
3967 delete TClinginfo;
3968 cl->fClassInfo = 0;
3969 std::string name(cl->GetName());
3970
3971 // Handle the special case of 'tuple' where we ignore the real implementation
3972 // details and just overlay a 'simpler'/'simplistic' version that is easy
3973 // for the I/O to understand and handle.
3974 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
3975
3976 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
3977
3978 }
3979
3980 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
3981 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
3982 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
3983 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
3984 // TClingClassInfoReadOnly.
3985 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
3986 if (!info->IsValid()) {
3987 if (cl->fState != TClass::kHasTClassInit) {
3988 if (cl->fStreamerInfo->GetEntries() != 0) {
3990 } else {
3992 }
3993 }
3994 delete info;
3995 return;
3996 }
3997 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
3998 // In case a class contains an external enum, the enum will be seen as a
3999 // class. We must detect this special case and make the class a Zombie.
4000 // Here we assume that a class has at least one method.
4001 // We can NOT call TClass::Property from here, because this method
4002 // assumes that the TClass is well formed to do a lot of information
4003 // caching. The method SetClassInfo (i.e. here) is usually called during
4004 // the building phase of the TClass, hence it is NOT well formed yet.
4005 Bool_t zombieCandidate = kFALSE;
4006 if (
4007 info->IsValid() &&
4008 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4009 ) {
4010 zombieCandidate = kTRUE;
4011 }
4012 if (!info->IsLoaded()) {
4013 if (info->Property() & (kIsNamespace)) {
4014 // Namespaces can have info but no corresponding CINT dictionary
4015 // because they are auto-created if one of their contained
4016 // classes has a dictionary.
4017 zombieCandidate = kTRUE;
4018 }
4019 // this happens when no dictionary is available
4020 delete info;
4021 cl->fClassInfo = 0;
4022 }
4023 if (zombieCandidate && !cl->GetCollectionType()) {
4024 cl->MakeZombie();
4025 }
4026 // If we reach here, the info was valid (See early returns).
4027 if (cl->fState != TClass::kHasTClassInit) {
4028 if (cl->fClassInfo) {
4031 } else {
4032// if (TClassEdit::IsSTLCont(cl->GetName()) {
4033// There will be an emulated collection proxy, is that the same?
4034// cl->fState = TClass::kEmulated;
4035// } else {
4036 if (cl->fStreamerInfo->GetEntries() != 0) {
4038 } else {
4040 }
4041// }
4042 }
4043 }
4044 if (cl->fClassInfo) {
4045 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4046 }
4047}
4048
4049////////////////////////////////////////////////////////////////////////////////
4050/// Checks if an entity with the specified name is defined in Cling.
4051/// Returns kUnknown if the entity is not defined.
4052/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4053/// Returns kKnown if the entity is defined.
4054///
4055/// By default, structs, namespaces, classes, enums and unions are looked for.
4056/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4057/// namespaces only are considered. I.e. if the name is an enum or a union,
4058/// the returned value is false.
4059///
4060/// In the case where the class is not loaded and belongs to a namespace
4061/// or is nested, looking for the full class name is outputting a lots of
4062/// (expected) error messages. Currently the only way to avoid this is to
4063/// specifically check that each level of nesting is already loaded.
4064/// In case of templates the idea is that everything between the outer
4065/// '<' and '>' has to be skipped, e.g.: aap<pippo<noot>::klaas>::a_class
4066
4068TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4069{
4071 static const char *anonEnum = "anonymous enum ";
4072 static const int cmplen = strlen(anonEnum);
4073
4074 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4075 return kUnknown;
4076 }
4077
4078 // Do not turn on the AutoLoading if it is globally off.
4079 autoload = autoload && IsClassAutoLoadingEnabled();
4080
4081 // Avoid the double search below in case the name is a fundamental type
4082 // or typedef to a fundamental type.
4083 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4084 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4085
4086 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4087 && fundType->GetType() > 0) {
4088 // Fundamental type, no a class.
4089 return kUnknown;
4090 }
4091
4092 // Migrated from within TClass::GetClass
4093 // If we want to know if a class or a namespace with this name exists in the
4094 // interpreter and this is an enum in the type system, before or after loading
4095 // according to the autoload function argument, return kUnknown.
4096 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4097 return kUnknown;
4098
4099 const char *classname = name;
4100
4101 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4102 class MaybeSuspendAutoLoadParse {
4103 int fStoreAutoLoad = 0;
4104 int fStoreAutoParse = 0;
4105 bool fSuspendedAutoParse = false;
4106 public:
4107 MaybeSuspendAutoLoadParse(int autoload) {
4108 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4109 }
4110
4111 void SuspendAutoParsing() {
4112 fSuspendedAutoParse = true;
4113 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4114 }
4115
4116 ~MaybeSuspendAutoLoadParse() {
4117 if (fSuspendedAutoParse)
4118 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4119 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4120 }
4121 };
4122
4123 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4124 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4125 autoLoadParseRAII.SuspendAutoParsing();
4126
4127 // First we want to check whether the decl exist, but _without_
4128 // generating any template instantiation. However, the lookup
4129 // still will create a forward declaration of the class template instance
4130 // if it exist. In this case, the return value of findScope will still
4131 // be zero but the type will be initialized.
4132 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4133 // this forward declaration.
4134 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4135 const clang::Type *type = 0;
4136 const clang::Decl *decl
4137 = lh.findScope(classname,
4138 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4139 : cling::LookupHelper::NoDiagnostics,
4140 &type, /* intantiateTemplate= */ false );
4141 if (!decl) {
4142 std::string buf = TClassEdit::InsertStd(classname);
4143 decl = lh.findScope(buf,
4144 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4145 : cling::LookupHelper::NoDiagnostics,
4146 &type,false);
4147 }
4148
4149 if (type) {
4150 // If decl==0 and the type is valid, then we have a forward declaration.
4151 if (!decl) {
4152 // If we have a forward declaration for a class template instantiation,
4153 // we want to ignore it if it was produced/induced by the call to
4154 // findScope, however we can not distinguish those from the
4155 // instantiation induce by 'soft' use (and thus also induce by the
4156 // same underlying code paths)
4157 // ['soft' use = use not requiring a complete definition]
4158 // So to reduce the amount of disruption to the existing code we
4159 // would just ignore those for STL collection, for which we really
4160 // need to have the compiled collection proxy (and thus the TClass
4161 // bootstrap).
4162 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4163 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4164 (type->getAsCXXRecordDecl());
4165 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4166 // Since the point of instantiation is invalid, we 'guess' that
4167 // the 'instantiation' of the forwarded type appended in
4168 // findscope.
4169 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4170 // For STL Collection we return kUnknown.
4171 return kUnknown;
4172 }
4173 }
4174 }
4176 if (!tci.IsValid()) {
4177 return kUnknown;
4178 }
4179 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4181
4182 if (tci.Property() & propertiesMask) {
4183 bool hasClassDefInline = false;
4184 if (isClassOrNamespaceOnly) {
4185 // We do not need to check for ClassDefInline when this is called from
4186 // TClass::Init, we only do it for the call from TClass::GetClass.
4187 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
4188 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
4189
4190 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4191 int lineNumber = 0;
4192 bool success = false;
4193 std::tie(success, lineNumber) =
4194 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4195 hasClassDefInline = success && (lineNumber == -1);
4196 }
4197 }
4198
4199 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4200 // , hasClassDefInline);
4201
4202 // We are now sure that the entry is not in fact an autoload entry.
4203 if (hasClassDefInline)
4204 return kWithClassDefInline;
4205 else
4206 return kKnown;
4207 } else {
4208 // We are now sure that the entry is not in fact an autoload entry.
4209 return kUnknown;
4210 }
4211 }
4212
4213 if (decl)
4214 return kKnown;
4215 else
4216 return kUnknown;
4217
4218 // Setting up iterator part of TClingTypedefInfo is too slow.
4219 // Copy the lookup code instead:
4220 /*
4221 TClingTypedefInfo t(fInterpreter, name);
4222 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4223 delete[] classname;
4224 return kTRUE;
4225 }
4226 */
4227
4228// const clang::Decl *decl = lh.findScope(name);
4229// if (!decl) {
4230// std::string buf = TClassEdit::InsertStd(name);
4231// decl = lh.findScope(buf);
4232// }
4233
4234// return (decl);
4235}
4236
4237////////////////////////////////////////////////////////////////////////////////
4238/// Return true if there is a class template by the given name ...
4239
4241{
4242 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4243 const clang::Decl *decl
4244 = lh.findClassTemplate(name,
4245 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4246 : cling::LookupHelper::NoDiagnostics);
4247 if (!decl) {
4248 std::string strname = "std::";
4249 strname += name;
4250 decl = lh.findClassTemplate(strname,
4251 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4252 : cling::LookupHelper::NoDiagnostics);
4253 }
4254 return 0 != decl;
4255}
4256
4257////////////////////////////////////////////////////////////////////////////////
4258/// Create list of pointers to base class(es) for TClass cl.
4259
4261{
4263 if (cl->fBase) {
4264 return;
4265 }
4267 if (!tci) return;
4269 TList *listOfBase = new TList;
4270 while (t.Next()) {
4271 // if name cannot be obtained no use to put in list
4272 if (t.IsValid() && t.Name()) {
4274 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4275 }
4276 }
4277 // Now that is complete, publish it.
4278 cl->fBase = listOfBase;
4279}
4280
4281////////////////////////////////////////////////////////////////////////////////
4282/// Create list of pointers to enums for TClass cl.
4283
4284void TCling::LoadEnums(TListOfEnums& enumList) const
4285{
4287
4288 const Decl * D;
4289 TClass* cl = enumList.GetClass();
4290 if (cl) {
4291 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4292 }
4293 else {
4294 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4295 }
4296 // Iterate on the decl of the class and get the enums.
4297 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4298 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4299 // Collect all contexts of the namespace.
4300 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4301 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4302 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4303 declIter != declEnd; ++declIter) {
4304 // Iterate on all decls for each context.
4305 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4306 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4307 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4308 // Get name of the enum type.
4309 std::string buf;
4310 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4311 llvm::raw_string_ostream stream(buf);
4312 // Don't trigger fopen of the source file to count lines:
4313 Policy.AnonymousTagLocations = false;
4314 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4315 stream.flush();
4316 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4317 if (!buf.empty()) {
4318 const char* name = buf.c_str();
4319 // Add the enum to the list of loaded enums.
4320 enumList.Get(ED, name);
4321 }
4322 }
4323 }
4324 }
4325 }
4326}
4327
4328////////////////////////////////////////////////////////////////////////////////
4329/// Create list of pointers to function templates for TClass cl.
4330
4332{
4334
4335 const Decl * D;
4336 TListOfFunctionTemplates* funcTempList;
4337 if (cl) {
4338 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4339 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4340 }
4341 else {
4342 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4343 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4344 }
4345 // Iterate on the decl of the class and get the enums.
4346 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4347 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4348 // Collect all contexts of the namespace.
4349 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4350 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4351 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4352 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4353 // Iterate on all decls for each context.
4354 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4355 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4356 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4357 funcTempList->Get(FTD);
4358 }
4359 }
4360 }
4361 }
4362}
4363
4364////////////////////////////////////////////////////////////////////////////////
4365/// Get the scopes representing using declarations of namespace
4366
4367std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4368{
4370 return ci->GetUsingNamespaces();
4371}
4372
4373////////////////////////////////////////////////////////////////////////////////
4374/// Create list of pointers to data members for TClass cl.
4375/// This is now a nop. The creation and updating is handled in
4376/// TListOfDataMembers.
4377
4379{
4380}
4381
4382////////////////////////////////////////////////////////////////////////////////
4383/// Create list of pointers to methods for TClass cl.
4384/// This is now a nop. The creation and updating is handled in
4385/// TListOfFunctions.
4386
4388{
4389}
4390
4391////////////////////////////////////////////////////////////////////////////////
4392/// Update the list of pointers to method for TClass cl
4393/// This is now a nop. The creation and updating is handled in
4394/// TListOfFunctions.
4395
4397{
4398}
4399
4400////////////////////////////////////////////////////////////////////////////////
4401/// Update the list of pointers to data members for TClass cl
4402/// This is now a nop. The creation and updating is handled in
4403/// TListOfDataMembers.
4404
4406{
4407}
4408
4409////////////////////////////////////////////////////////////////////////////////
4410/// Create list of pointers to method arguments for TMethod m.
4411
4413{
4415 if (m->fMethodArgs) {
4416 return;
4417 }
4418 TList *arglist = new TList;
4420 while (t.Next()) {
4421 if (t.IsValid()) {
4423 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4424 }
4425 }
4426 m->fMethodArgs = arglist;
4427}
4428
4429
4430////////////////////////////////////////////////////////////////////////////////
4431/// Generate a TClass for the given class.
4432/// Since the caller has already check the ClassInfo, let it give use the
4433/// result (via the value of emulation) rather than recalculate it.
4434
4435TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4436{
4437// For now the following line would lead to the (unwanted) instantiation
4438// of class template. This could/would need to be resurrected only if
4439// we re-introduce so sort of automatic instantiation. However this would
4440// have to include carefull look at the template parameter to avoid
4441// creating instance we can not really use (if the parameter are only forward
4442// declaration or do not have all the necessary interfaces).
4443
4444 // TClingClassInfo tci(fInterpreter, classname);
4445 // if (1 || !tci.IsValid()) {
4446
4447 Version_t version = 1;
4448 if (TClassEdit::IsSTLCont(classname)) {
4449 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4450 }
4452 TClass *cl = new TClass(classname, version, silent);
4453 if (emulation) {
4455 } else {
4456 // Set the class version if the class is versioned.
4457 // Note that we cannot just call CLASS::Class_Version() as we might not have
4458 // an execution engine (when invoked from rootcling).
4459
4460 // Do not call cl->GetClassVersion(), it has side effects!
4461 Version_t oldvers = cl->fClassVersion;
4462 if (oldvers == version && cl->GetClassInfo()) {
4463 // We have a version and it might need an update.
4464 Version_t newvers = oldvers;
4466 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4467 // Namespaces don't have class versions.
4468 return cl;
4469 }
4470 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4473 if (!mi.IsValid()) {
4474 if (cl->TestBit(TClass::kIsTObject)) {
4475 Error("GenerateTClass",
4476 "Cannot find %s::Class_Version()! Class version might be wrong.",
4477 cl->GetName());
4478 }
4479 return cl;
4480 }
4481 newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4482 *fInterpreter);
4483 if (newvers == -1) {
4484 // Didn't manage to determine the class version from the AST.
4485 // Use runtime instead.
4486 if ((mi.Property() & kIsStatic)
4487 && !fInterpreter->isInSyntaxOnlyMode()) {
4488 // This better be a static function.
4490 callfunc.SetFunc(&mi);
4491 newvers = callfunc.ExecInt(0);
4492 } else {
4493 Error("GenerateTClass",
4494 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4495 cl->GetName());
4496 }
4497 }
4498 if (newvers != oldvers) {
4499 cl->fClassVersion = newvers;
4500 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4501 }
4502 }
4503 }
4504
4505 return cl;
4506
4507// } else {
4508// return GenerateTClass(&tci,silent);
4509// }
4510}
4511
4512#if 0
4513////////////////////////////////////////////////////////////////////////////////
4514
4515static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4516{
4517 includes += info->FileName();
4518
4519 const clang::ClassTemplateSpecializationDecl *templateCl
4520 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4521 if (templateCl) {
4522 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4523 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4524 if (arg.getKind() == clang::TemplateArgument::Type) {
4525 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4526
4527 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4528 // We really need a header file.
4529 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4530 if (argdecl) {
4531 includes += ";";
4532 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4533 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4534 } else {
4535 std::string Result;
4536 llvm::raw_string_ostream OS(Result);
4537 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4538 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4539 }
4540 }
4541 }
4542 }
4543 }
4544}
4545#endif
4546
4547////////////////////////////////////////////////////////////////////////////////
4548/// Generate a TClass for the given class.
4549
4550TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4551{
4552 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4553 if (!info || !info->IsValid()) {
4554 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4555 return 0;
4556 }
4557 // We are in the case where we have AST nodes for this class.
4558 TClass *cl = 0;
4559 std::string classname;
4560 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4561 if (TClassEdit::IsSTLCont(classname)) {
4562#if 0
4563 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4564 // We need to build up the list of required headers, by
4565 // looking at each template arguments.
4566 TString includes;
4567 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4568
4569 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4570 // 0 means success.
4571 cl = TClass::LoadClass(classnam.c_str(), silent);
4572 if (cl == 0) {
4573 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4574 }
4575 }
4576#endif
4577 if (cl == 0) {
4578 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4579 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4581 }
4582 } else {
4583 // For regular class, just create a TClass on the fly ...
4584 // Not quite useful yet, but that what CINT used to do anyway.
4585 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4586 }
4587 // Add the new TClass to the map of declid and TClass*.
4588 if (cl) {
4590 }
4591 return cl;
4592}
4593
4594////////////////////////////////////////////////////////////////////////////////
4595/// Generate the dictionary for the C++ classes listed in the first
4596/// argument (in a semi-colon separated list).
4597/// 'includes' contains a semi-colon separated list of file to
4598/// #include in the dictionary.
4599/// For example:
4600/// ~~~ {.cpp}
4601/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4602/// ~~~
4603/// or
4604/// ~~~ {.cpp}
4605/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4606/// ~~~
4607
4608Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4609{
4610 if (classes == 0 || classes[0] == 0) {
4611 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4612 return 0;
4613 }
4614 // Split the input list
4615 std::vector<std::string> listClasses;
4616 for (
4617 const char* current = classes, *prev = classes;
4618 *current != 0;
4619 ++current
4620 ) {
4621 if (*current == ';') {
4622 listClasses.push_back(std::string(prev, current - prev));
4623 prev = current + 1;
4624 }
4625 else if (*(current + 1) == 0) {
4626 listClasses.push_back(std::string(prev, current + 1 - prev));
4627 prev = current + 1;
4628 }
4629 }
4630 std::vector<std::string> listIncludes;
4631 if (!includes)
4632 includes = "";
4633 for (
4634 const char* current = includes, *prev = includes;
4635 *current != 0;
4636 ++current
4637 ) {
4638 if (*current == ';') {
4639 listIncludes.push_back(std::string(prev, current - prev));
4640 prev = current + 1;
4641 }
4642 else if (*(current + 1) == 0) {
4643 listIncludes.push_back(std::string(prev, current + 1 - prev));
4644 prev = current + 1;
4645 }
4646 }
4647 // Generate the temporary dictionary file
4648 return !TCling_GenerateDictionary(listClasses, listIncludes,
4649 std::vector<std::string>(), std::vector<std::string>());
4650}
4651
4652////////////////////////////////////////////////////////////////////////////////
4653/// Return pointer to cling Decl of global/static variable that is located
4654/// at the address given by addr.
4655
4656TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4657{
4659 DeclId_t d;
4660 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4661
4662 if (cl) {
4663 d = cl->GetDataMember(name);
4664 // We check if the decl of the data member has an annotation which indicates
4665 // an ioname.
4666 // In case this is true, if the name requested is not the ioname, we
4667 // return 0, as if the member did not exist. In some sense we override
4668 // the information in the TClassInfo instance, isolating the typesystem in
4669 // TClass from the one in the AST.
4670 if (const ValueDecl* decl = (const ValueDecl*) d){
4671 std::string ioName;
4672 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4673 if (hasIoName && ioName != name) return 0;
4674 }
4675 return d;
4676 }
4677 // We are looking up for something on the TU scope.
4678 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4679 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4680 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4681 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4682 // are only fulfilling ROOT's understanding for a Data Member.
4683 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4684 // similar as below.
4685 using namespace clang;
4686 Sema& SemaR = fInterpreter->getSema();
4687 DeclarationName DName = &SemaR.Context.Idents.get(name);
4688
4689 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4690 Sema::ForExternalRedeclaration);
4691
4692 // Could trigger deserialization of decls.
4693 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4694 cling::utils::Lookup::Named(&SemaR, R);
4695
4696 LookupResult::Filter F = R.makeFilter();
4697 // Filter the data-member looking decls.
4698 while (F.hasNext()) {
4699 NamedDecl *D = F.next();
4700 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4701 isa<IndirectFieldDecl>(D))
4702 continue;
4703 F.erase();
4704 }
4705 F.done();
4706
4707 if (R.isSingleResult())
4708 return R.getFoundDecl();
4709 return 0;
4710}
4711
4712////////////////////////////////////////////////////////////////////////////////
4713/// Return pointer to cling Decl of global/static variable that is located
4714/// at the address given by addr.
4715
4717{
4719
4720 const clang::Decl* possibleEnum = 0;
4721 // FInd the context of the decl.
4722 if (cl) {
4724 if (cci) {
4725 const clang::DeclContext* dc = 0;
4726 if (const clang::Decl* D = cci->GetDecl()) {
4727 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4728 dc = dyn_cast<clang::RecordDecl>(D);
4729 }
4730 }
4731 if (dc) {
4732 // If it is a data member enum.
4733 // Could trigger deserialization of decls.
4734 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4735 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4736 } else {
4737 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4738 }
4739 }
4740 } else {
4741 // If it is a global enum.
4742 // Could trigger deserialization of decls.
4743 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4744 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4745 }
4746 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4747 && isa<clang::EnumDecl>(possibleEnum)) {
4748 return possibleEnum;
4749 }
4750 return 0;
4751}
4752
4753////////////////////////////////////////////////////////////////////////////////
4754/// Return pointer to cling DeclId for a global value
4755
4756TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4757{
4758 if (!gv) return 0;
4759
4760 llvm::StringRef mangled_name = gv->getName();
4761
4762 int err = 0;
4763 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4764 if (err) {
4765 if (err == -2) {
4766 // It might simply be an unmangled global name.
4767 DeclId_t d;
4769 d = gcl.GetDataMember(mangled_name.str().c_str());
4770 return d;
4771 }
4772 return 0;
4773 }
4774
4775 std::string scopename(demangled_name_c);
4776 free(demangled_name_c);
4777
4778 //
4779 // Separate out the class or namespace part of the
4780 // function name.
4781 //
4782 std::string dataname;
4783
4784 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4785 scopename.erase(0, sizeof("typeinfo for ")-1);
4786 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4787 scopename.erase(0, sizeof("vtable for ")-1);
4788 } else {
4789 // See if it is a function
4790 std::string::size_type pos = scopename.rfind('(');
4791 if (pos != std::string::npos) {
4792 return 0;
4793 }
4794 // Separate the scope and member name
4795 pos = scopename.rfind(':');
4796 if (pos != std::string::npos) {
4797 if ((pos != 0) && (scopename[pos-1] == ':')) {
4798 dataname = scopename.substr(pos+1);
4799 scopename.erase(pos-1);
4800 }
4801 } else {
4802 scopename.clear();
4803 dataname = scopename;
4804 }
4805 }
4806 //fprintf(stderr, "name: '%s'\n", name.c_str());
4807 // Now we have the class or namespace name, so do the lookup.
4808
4809
4810 DeclId_t d;
4811 if (scopename.size()) {
4812 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4813 d = cl.GetDataMember(dataname.c_str());
4814 }
4815 else {
4817 d = gcl.GetDataMember(dataname.c_str());
4818 }
4819 return d;
4820}
4821
4822////////////////////////////////////////////////////////////////////////////////
4823/// NOT IMPLEMENTED.
4824
4826{
4827 Error("GetDataMemberWithValue()", "not implemented");
4828 return 0;
4829}
4830
4831////////////////////////////////////////////////////////////////////////////////
4832/// Return pointer to cling DeclId for a data member with a given name.
4833
4835{
4836 // NOT IMPLEMENTED.
4837 Error("GetDataMemberAtAddr()", "not implemented");
4838 return 0;
4839}
4840
4841////////////////////////////////////////////////////////////////////////////////
4842/// Return the cling mangled name for a method of a class with parameters
4843/// params (params is a string of actual arguments, not formal ones). If the
4844/// class is 0 the global function list will be searched.
4845
4846TString TCling::GetMangledName(TClass* cl, const char* method,
4847 const char* params, Bool_t objectIsConst /* = kFALSE */)
4848{
4851 if (cl) {
4852 Long_t offset;
4853 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4854 &offset);
4855 }
4856 else {
4858 Long_t offset;
4859 func.SetFunc(&gcl, method, params, &offset);
4860 }
4862 if (!mi) return "";
4863 TString mangled_name( mi->GetMangledName() );
4864 delete mi;
4865 return mangled_name;
4866}
4867
4868////////////////////////////////////////////////////////////////////////////////
4869/// Return the cling mangled name for a method of a class with a certain
4870/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4871/// list will be searched.
4872
4874 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4875 EFunctionMatchMode mode /* = kConversionMatch */)
4876{
4878 if (cl) {
4879 return ((TClingClassInfo*)cl->GetClassInfo())->
4880 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4881 }
4883 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4884}
4885
4886////////////////////////////////////////////////////////////////////////////////
4887/// Return pointer to cling interface function for a method of a class with
4888/// parameters params (params is a string of actual arguments, not formal
4889/// ones). If the class is 0 the global function list will be searched.
4890
4891void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4892 const char* params, Bool_t objectIsConst /* = kFALSE */)
4893{
4896 if (cl) {
4897 Long_t offset;
4898 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4899 &offset);
4900 }
4901 else {
4903 Long_t offset;
4904 func.SetFunc(&gcl, method, params, &offset);
4905 }
4906 return (void*) func.InterfaceMethod();
4907}
4908
4909////////////////////////////////////////////////////////////////////////////////
4910/// Return pointer to cling interface function for a method of a class with
4911/// a certain name.
4912
4913TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4914{
4916 DeclId_t f;
4917 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4918 if (cl) {
4919 f = cl->GetMethod(method).GetDeclId();
4920 }
4921 else {
4923 f = gcl.GetMethod(method).GetDeclId();
4924 }
4925 return f;
4926
4927}
4928
4929////////////////////////////////////////////////////////////////////////////////
4930/// Insert overloads of name in cl to res.
4931
4932void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
4933 std::vector<DeclId_t>& res) const
4934{
4935 clang::Sema& S = fInterpreter->getSema();
4936 clang::ASTContext& Ctx = S.Context;
4937 const clang::Decl* CtxDecl
4938 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4939 Ctx.getTranslationUnitDecl();
4940 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4941 const clang::DeclContext* DeclCtx = RecDecl;
4942
4943 if (!DeclCtx)
4944 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4945 if (!DeclCtx) return;
4946
4947 clang::DeclarationName DName;
4948 // The DeclarationName is funcname, unless it's a ctor or dtor.
4949 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
4950
4951 if (RecDecl) {
4952 if (RecDecl->getNameAsString() == funcname) {
4953 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4954 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4955 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
4956 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4957 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4958 } else {
4959 DName = &Ctx.Idents.get(funcname);
4960 }
4961 } else {
4962 DName = &Ctx.Idents.get(funcname);
4963 }
4964
4965 // NotForRedeclaration: we want to find names in inline namespaces etc.
4966 clang::LookupResult R(S, DName, clang::SourceLocation(),
4967 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
4968 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
4969 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
4970 if (R.empty()) return;
4971 R.resolveKind();
4972 res.reserve(res.size() + (R.end() - R.begin()));
4973 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
4974 IR != ER; ++IR) {
4975 if (const clang::FunctionDecl* FD
4976 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
4977 if (!FD->getDescribedFunctionTemplate()) {
4978 res.push_back(FD);
4979 }
4980 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
4981 // FIXME: multi-level using
4982 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
4983 res.push_back(USD);
4984 }
4985 }
4986 }
4987}
4988
4989////////////////////////////////////////////////////////////////////////////////
4990/// Return pointer to cling interface function for a method of a class with
4991/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4992/// function list will be searched.
4993
4995 const char* proto,
4996 Bool_t objectIsConst /* = kFALSE */,
4997 EFunctionMatchMode mode /* = kConversionMatch */)
4998{
5000 void* f;
5001 if (cl) {
5002 f = ((TClingClassInfo*)cl->GetClassInfo())->
5003 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
5004 }
5005 else {
5007 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
5008 }
5009 return f;
5010}
5011
5012////////////////////////////////////////////////////////////////////////////////
5013/// Return pointer to cling DeclId for a method of a class with
5014/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5015/// function list will be searched.
5016
5017TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5018 const char* params,
5019 Bool_t objectIsConst /* = kFALSE */)
5020{
5022 DeclId_t f;
5023 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5024 if (cl) {
5025 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5026 }
5027 else {
5029 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5030 }
5031 return f;
5032}
5033
5034////////////////////////////////////////////////////////////////////////////////
5035/// Return pointer to cling interface function for a method of a class with
5036/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5037/// function list will be searched.
5038
5039TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5040 const char* proto,
5041 Bool_t objectIsConst /* = kFALSE */,
5042 EFunctionMatchMode mode /* = kConversionMatch */)
5043{
5045 DeclId_t f;
5046 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5047 if (cl) {
5048 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5049 }
5050 else {
5052 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5053 }
5054 return f;
5055}
5056
5057////////////////////////////////////////////////////////////////////////////////
5058/// Return pointer to cling interface function for a method of a class with
5059/// a certain name.
5060
5061TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5062{
5064 DeclId_t f;
5065 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5066 if (cl) {
5067 f = cl->GetFunctionTemplate(name);
5068 }
5069 else {
5071 f = gcl.GetFunctionTemplate(name);
5072 }
5073 return f;
5074
5075}
5076
5077////////////////////////////////////////////////////////////////////////////////
5078/// The 'name' is known to the interpreter, this function returns
5079/// the internal version of this name (usually just resolving typedefs)
5080/// This is used in particular to synchronize between the name used
5081/// by rootcling and by the run-time environment (TClass)
5082/// Return 0 if the name is not known.
5083
5084void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5085{
5086 output.clear();
5087
5089
5091 if (!cl.IsValid()) {
5092 return ;
5093 }
5094 if (full) {
5096 return;
5097 }
5098 // Well well well, for backward compatibility we need to act a bit too
5099 // much like CINT.
5102
5103 return;
5104}
5105
5106////////////////////////////////////////////////////////////////////////////////
5107/// Execute a global function with arguments params.
5108///
5109/// FIXME: The cint-based version of this code does not check if the
5110/// SetFunc() call works, and does not do any real checking
5111/// for errors from the Exec() call. It did fetch the most
5112/// recent cint security error and return that in error, but
5113/// this does not really translate well to cling/clang. We
5114/// should enhance these interfaces so that we can report
5115/// compilation and runtime errors properly.
5116
5117void TCling::Execute(const char* function, const char* params, int* error)
5118{
5120 if (error) {
5121 *error = TInterpreter::kNoError;
5122 }
5124 Long_t offset = 0L;
5126 func.SetFunc(&cl, function, params, &offset);
5127 func.Exec(0);
5128}
5129
5130////////////////////////////////////////////////////////////////////////////////
5131/// Execute a method from class cl with arguments params.
5132///
5133/// FIXME: The cint-based version of this code does not check if the
5134/// SetFunc() call works, and does not do any real checking
5135/// for errors from the Exec() call. It did fetch the most
5136/// recent cint security error and return that in error, but
5137/// this does not really translate well to cling/clang. We
5138/// should enhance these interfaces so that we can report
5139/// compilation and runtime errors properly.
5140
5141void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5142 const char* params, Bool_t objectIsConst, int* error)
5143{
5145 if (error) {
5146 *error = TInterpreter::kNoError;
5147 }
5148 // If the actual class of this object inherits 2nd (or more) from TObject,
5149 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5150 // hence gInterpreter->Execute will improperly correct the offset.
5151 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5152 Long_t offset = 0L;
5154 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5155 void* address = (void*)((Long_t)addr + offset);
5156 func.Exec(address);
5157}
5158
5159////////////////////////////////////////////////////////////////////////////////
5160
5161void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5162 const char* params, int* error)
5163{
5164 Execute(obj,cl,method,params,false,error);
5165}
5166
5167////////////////////////////////////////////////////////////////////////////////
5168/// Execute a method from class cl with the arguments in array params
5169/// (params[0] ... params[n] = array of TObjString parameters).
5170/// Convert the TObjArray array of TObjString parameters to a character
5171/// string of comma separated parameters.
5172/// The parameters of type 'char' are enclosed in double quotes and all
5173/// internal quotes are escaped.
5174
5175void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5176 TObjArray* params, int* error)
5177{
5178 if (!method) {
5179 Error("Execute", "No method was defined");
5180 return;
5181 }
5182 TList* argList = method->GetListOfMethodArgs();
5183 // Check number of actual parameters against of expected formal ones
5184
5185 Int_t nparms = argList->LastIndex() + 1;
5186 Int_t argc = params ? params->GetEntries() : 0;
5187
5188 if (argc > nparms) {
5189 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5190 return;
5191 }
5192 if (nparms != argc) {
5193 // Let's see if the 'missing' argument are all defaulted.
5194 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5195 assert(nparms > 0);
5196
5197 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5198 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5199 // There is a default value for the first missing
5200 // argument, so we are fine.
5201 } else {
5202 Int_t firstDefault = -1;
5203 for (Int_t i = 0; i < nparms; i ++) {
5204 arg = (TMethodArg *) argList->At( i );
5205 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5206 firstDefault = i;
5207 break;
5208 }
5209 }
5210 if (firstDefault >= 0) {
5211 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);
5212 } else {
5213 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5214 }
5215 return;
5216 }
5217 }
5218
5219 const char* listpar = "";
5220 TString complete(10);
5221 if (params) {
5222 // Create a character string of parameters from TObjArray
5223 TIter next(params);
5224 for (Int_t i = 0; i < argc; i ++) {
5225 TMethodArg* arg = (TMethodArg*) argList->At(i);
5227 TObjString* nxtpar = (TObjString*) next();
5228 if (i) {
5229 complete += ',';
5230 }
5231 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5232 TString chpar('\"');
5233 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5234 // At this point we have to check if string contains \\"
5235 // and apply some more sophisticated parser. Not implemented yet!
5236 complete += chpar;
5237 complete += '\"';
5238 }
5239 else {
5240 complete += nxtpar->String();
5241 }
5242 }
5243 listpar = complete.Data();
5244 }
5245
5246 // And now execute it.
5248 if (error) {
5249 *error = TInterpreter::kNoError;
5250 }
5251 // If the actual class of this object inherits 2nd (or more) from TObject,
5252 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5253 // hence gInterpreter->Execute will improperly correct the offset.
5254 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5256 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5257 func.Init(*minfo);
5258 func.SetArgs(listpar);
5259 // Now calculate the 'this' pointer offset for the method
5260 // when starting from the class described by cl.
5261 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5262 Long_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5263 void* address = (void*)((Long_t)addr + offset);
5264 func.Exec(address);
5265}
5266
5267////////////////////////////////////////////////////////////////////////////////
5268
5269void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5270 const void* args[] /*=0*/,
5271 int nargs /*=0*/,
5272 void* ret/*= 0*/) const
5273{
5274 if (!method) {
5275 Error("ExecuteWithArgsAndReturn", "No method was defined");
5276 return;
5277 }
5278
5279 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5280 TClingCallFunc func(*minfo,*fNormalizedCtxt);
5281 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5282}
5283
5284////////////////////////////////////////////////////////////////////////////////
5285/// Execute a cling macro.
5286
5287Long_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
5288{
5290 fCurExecutingMacros.push_back(filename);
5291 Long_t result = TApplication::ExecuteFile(filename, (int*)error);
5292 fCurExecutingMacros.pop_back();
5293 return result;
5294}
5295
5296////////////////////////////////////////////////////////////////////////////////
5297/// Return the file name of the current un-included interpreted file.
5298/// See the documentation for GetCurrentMacroName().
5299
5301{
5302 Warning("GetTopLevelMacroName", "Must change return type!");
5303 return fCurExecutingMacros.back();
5304}
5305
5306////////////////////////////////////////////////////////////////////////////////
5307/// Return the file name of the currently interpreted file,
5308/// included or not. Example to illustrate the difference between
5309/// GetCurrentMacroName() and GetTopLevelMacroName():
5310/// ~~~ {.cpp}
5311/// void inclfile() {
5312/// std::cout << "In inclfile.C" << std::endl;
5313/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5314/// TCling::GetCurrentMacroName() << std::endl;
5315/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5316/// TCling::GetTopLevelMacroName() << std::endl;
5317/// }
5318/// ~~~
5319/// ~~~ {.cpp}
5320/// void mymacro() {
5321/// std::cout << "In mymacro.C" << std::endl;
5322/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5323/// TCling::GetCurrentMacroName() << std::endl;
5324/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5325/// TCling::GetTopLevelMacroName() << std::endl;
5326/// std::cout << " Now calling inclfile..." << std::endl;
5327/// gInterpreter->ProcessLine(".x inclfile.C");;
5328/// }
5329/// ~~~
5330/// Running mymacro.C will print:
5331///
5332/// ~~~ {.cpp}
5333/// root [0] .x mymacro.C
5334/// ~~~
5335/// In mymacro.C
5336/// ~~~ {.cpp}
5337/// TCling::GetCurrentMacroName() returns ./mymacro.C
5338/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5339/// ~~~
5340/// Now calling inclfile...
5341/// In inclfile.h
5342/// ~~~ {.cpp}
5343/// TCling::GetCurrentMacroName() returns inclfile.C
5344/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5345/// ~~~
5346
5348{
5349#if defined(R__MUST_REVISIT)
5350#if R__MUST_REVISIT(6,0)
5351 Warning("GetCurrentMacroName", "Must change return type!");
5352#endif
5353#endif
5354 return fCurExecutingMacros.back();
5355}
5356
5357////////////////////////////////////////////////////////////////////////////////
5358/// Return the absolute type of typeDesc.
5359/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5360/// You need to use the result immediately before it is being overwritten.
5361
5362const char* TCling::TypeName(const char* typeDesc)
5363{
5364 TTHREAD_TLS(char*) t = 0;
5365 TTHREAD_TLS(unsigned int) tlen = 0;
5366
5367 unsigned int dlen = strlen(typeDesc);
5368 if (dlen > tlen) {
5369 delete[] t;
5370 t = new char[dlen + 1];
5371 tlen = dlen;
5372 }
5373 const char* s, *template_start;
5374 if (!strstr(typeDesc, "(*)(")) {
5375 s = strchr(typeDesc, ' ');
5376 template_start = strchr(typeDesc, '<');
5377 if (!strcmp(typeDesc, "long long")) {
5378 strlcpy(t, typeDesc, dlen + 1);
5379 }
5380 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5381 strlcpy(t, typeDesc, dlen + 1);
5382 }
5383 // s is the position of the second 'word' (if any)
5384 // except in the case of templates where there will be a space
5385 // just before any closing '>': eg.
5386 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5387 else if (s && (template_start == 0 || (s < template_start))) {
5388 strlcpy(t, s + 1, dlen + 1);
5389 }
5390 else {
5391 strlcpy(t, typeDesc, dlen + 1);
5392 }
5393 }
5394 else {
5395 strlcpy(t, typeDesc, dlen + 1);
5396 }
5397 int l = strlen(t);
5398 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&')) {
5399 t[--l] = 0;
5400 }
5401 return t;
5402}
5403
5404static bool requiresRootMap(const char* rootmapfile)
5405{
5406 assert(rootmapfile && *rootmapfile);
5407
5408 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5409 libName.consume_back(".rootmap");
5410
5411 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5412}
5413
5414////////////////////////////////////////////////////////////////////////////////
5415/// Read and parse a rootmapfile in its new format, and return 0 in case of
5416/// success, -1 if the file has already been read, and -3 in case its format
5417/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5418/// error.
5419
5420int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5421{
5422 if (!(rootmapfile && *rootmapfile))
5423 return 0;
5424
5425 if (!requiresRootMap(rootmapfile))
5426 return 0; // success
5427
5428 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5429 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5430
5431 std::string rootmapfileNoBackslash(rootmapfile);
5432#ifdef _MSC_VER
5433 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5434#endif
5435 // Add content of a specific rootmap file
5436 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5437 return -1;
5438
5439 // Line 1 is `{ decls }`
5440 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5441
5442 std::ifstream file(rootmapfileNoBackslash);
5443 std::string line;
5444 line.reserve(200);
5445 std::string lib_name;
5446 line.reserve(100);
5447 bool newFormat = false;
5448 while (getline(file, line, '\n')) {
5449 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5450 file.close();
5451 return -3; // old format
5452 }
5453 newFormat = true;
5454
5455 if (line.compare(0, 9, "{ decls }") == 0) {
5456 // forward declarations
5457
5458 while (getline(file, line, '\n')) {
5459 if (line[0] == '[')
5460 break;
5461 if (!uniqueString) {
5462 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5463 rootmapfileNoBackslash.c_str());
5464 return -4;
5465 }
5466 if (!lineDirective.empty())
5467 uniqueString->Append(lineDirective);
5468 uniqueString->Append(line + '\n');
5469 }
5470 }
5471 const char firstChar = line[0];
5472 if (firstChar == '[') {
5473 // new section (library)
5474 auto brpos = line.find(']');
5475 if (brpos == string::npos)
5476 continue;
5477 lib_name = line.substr(1, brpos - 1);
5478 size_t nspaces = 0;
5479 while (lib_name[nspaces] == ' ')
5480 ++nspaces;
5481 if (nspaces)
5482 lib_name.replace(0, nspaces, "");
5483 if (gDebug > 3) {
5484 TString lib_nameTstr(lib_name.c_str());
5485 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5486 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5487 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5488 if (wlib) {
5489 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5490 } else {
5491 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5492 }
5493 delete[] wlib;
5494 delete tokens;
5495 }
5496 } else {
5497 auto keyLenIt = keyLenMap.find(firstChar);
5498 if (keyLenIt == keyLenMap.end())
5499 continue;
5500 unsigned int keyLen = keyLenIt->second;
5501 // Do not make a copy, just start after the key
5502 const char *keyname = line.c_str() + keyLen;
5503 if (gDebug > 6)
5504 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5505 TEnvRec *isThere = fMapfile->Lookup(keyname);
5506 if (isThere) {
5507 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5508 if (firstChar == 'n') {
5509 if (gDebug > 3)
5510 Info("ReadRootmapFile", "namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5511 isThere->GetValue());
5512 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5513 lib_name += " ";
5514 lib_name += isThere->GetValue();
5515 fMapfile->SetValue(keyname, lib_name.c_str());
5516 } else if (!TClassEdit::IsSTLCont(keyname)) {
5517 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5518 keyname, lib_name.c_str(), isThere->GetValue());
5519 }
5520 } else { // the same key for the same lib
5521 if (gDebug > 3)
5522 Info("ReadRootmapFile", "Key %s was already defined for %s", keyname, lib_name.c_str());
5523 }
5524 } else {
5525 fMapfile->SetValue(keyname, lib_name.c_str());
5526 }
5527 }
5528 }
5529 file.close();
5530 return 0;
5531}
5532
5533////////////////////////////////////////////////////////////////////////////////
5534/// Create a resource table and read the (possibly) three resource files,
5535/// i.e.\ $ROOTSYS/etc/system<name> (or ROOTETCDIR/system<name>), $HOME/<name>
5536/// and $PWD/<name>. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5537/// can read additional user defined resource files by creating additional TEnv
5538/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5539/// the $HOME/<name> resource file will be skipped. This might be useful in
5540/// case the home directory resides on an automounted remote file system
5541/// and one wants to avoid the file system from being mounted.
5542
5544{
5545 assert(requiresRootMap(name) && "We have a module!");
5546
5547 if (!requiresRootMap(name))
5548 return;
5549
5551
5553
5554 TString sname = "system";
5555 sname += name;
5556 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5557
5558 Int_t ret = ReadRootmapFile(s);
5559 if (ret == -3) // old format
5561 delete [] s;
5562 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5564 ret = ReadRootmapFile(s);
5565 if (ret == -3) // old format
5567 delete [] s;
5568 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5569 ret = ReadRootmapFile(name);
5570 if (ret == -3) // old format
5572 }
5573 } else {
5574 ret = ReadRootmapFile(name);
5575 if (ret == -3) // old format
5577 }
5578 fMapfile->IgnoreDuplicates(ignore);
5579}
5580
5581
5582namespace {
5583 using namespace clang;
5584
5585 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5586 // This class is to be considered an helper for AutoLoading.
5587 // It is a recursive visitor is used to inspect namespaces and specializations
5588 // coming from forward declarations in rootmaps and to set the external visible
5589 // storage flag for them.
5590 public:
5591 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5592 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5593 // We want to enable the external lookup for this namespace
5594 // because it may shadow the lookup of other names contained
5595 // in that namespace
5596
5597 nsDecl->setHasExternalVisibleStorage();
5598 fNSSet.insert(nsDecl);
5599 return true;
5600 }
5601 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5602 // We want to enable the external lookup for this specialization
5603 // because we can provide a definition for it!
5604 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5605 //SpecSet.insert(specDecl);
5606 specDecl->setHasExternalLexicalStorage();
5607
5608 // No need to recurse. On the contrary, recursing is actively harmful:
5609 // NOTE: must not recurse to prevent this visitor from triggering loading from
5610 // the external AST source (i.e. autoloading). This would be triggered right here,
5611 // before autoloading is even set up, as rootmap file parsing happens before that.
5612 // Even if autoloading is off and has no effect, triggering loading from external
5613 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5614 // from subsequent autoloads!
5615 return false;
5616 }
5617 private:
5618 std::unordered_set<const NamespaceDecl*>& fNSSet;
5619 };
5620}
5621
5622////////////////////////////////////////////////////////////////////////////////
5623/// Load map between class and library. If rootmapfile is specified a
5624/// specific rootmap file can be added (typically used by ACLiC).
5625/// In case of error -1 is returned, 0 otherwise.
5626/// The interpreter uses this information to automatically load the shared
5627/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5628
5629Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5630{
5631 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5632 return 0;
5633
5635
5636 // open the [system].rootmap files
5637 if (!fMapfile) {
5638 fMapfile = new TEnv();
5642 InitRootmapFile(".rootmap");
5643 }
5644
5645 // Prepare a list of all forward declarations for cling
5646 // For some experiments it is easily as big as 500k characters. To be on the
5647 // safe side, we go for 1M.
5648 TUniqueString uniqueString(1048576);
5649
5650 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5651 // A rootmap file must end with the string ".rootmap".
5652 TString ldpath = gSystem->GetDynamicPath();
5653 if (ldpath != fRootmapLoadPath) {
5654 fRootmapLoadPath = ldpath;
5655#ifdef WIN32
5656 TObjArray* paths = ldpath.Tokenize(";");
5657#else
5658 TObjArray* paths = ldpath.Tokenize(":");
5659#endif
5660 TString d;
5661 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5662 d = ((TObjString *)paths->At(i))->GetString();
5663 // check if directory already scanned
5664 Int_t skip = 0;
5665 for (Int_t j = 0; j < i; j++) {
5666 TString pd = ((TObjString *)paths->At(j))->GetString();
5667 if (pd == d) {
5668 skip++;
5669 break;
5670 }
5671 }
5672 if (!skip) {
5673 void* dirp = gSystem->OpenDirectory(d);
5674 if (dirp) {
5675 if (gDebug > 3) {
5676 Info("LoadLibraryMap", "%s", d.Data());
5677 }
5678 const char* f1;
5679 while ((f1 = gSystem->GetDirEntry(dirp))) {
5680 TString f = f1;
5681 if (f.EndsWith(".rootmap")) {
5682 TString p;
5683 p = d + "/" + f;
5685 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5686 if (gDebug > 4) {
5687 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5688 }
5689 Int_t ret = ReadRootmapFile(p, &uniqueString);
5690
5691 if (ret == 0)
5693 if (ret == -3) {
5694 // old format
5696 fRootmapFiles->Add(new TNamed(f, p));
5697 }
5698 }
5699 // else {
5700 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5701 // fRootmapFiles->FindObject(f)->ls();
5702 // }
5703 }
5704 }
5705 if (f.BeginsWith("rootmap")) {
5706 TString p;
5707 p = d + "/" + f;
5708 FileStat_t stat;
5709 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5710 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5711 }
5712 }
5713 }
5714 }
5715 gSystem->FreeDirectory(dirp);
5716 }
5717 }
5718 delete paths;
5719 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5720 return -1;
5721 }
5722 }
5723 if (rootmapfile && *rootmapfile) {
5724 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5725 if (res == 0) {
5726 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5727 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5728 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5729 }
5730 else if (res == -3) {
5731 // old format
5733 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5734 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5735 fMapfile->IgnoreDuplicates(ignore);
5736 }
5737 }
5738 TEnvRec* rec;
5739 TIter next(fMapfile->GetTable());
5740 while ((rec = (TEnvRec*) next())) {
5741 TString cls = rec->GetName();
5742 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5743 // get the first lib from the list of lib and dependent libs
5744 TString libs = rec->GetValue();
5745 if (libs == "") {
5746 continue;
5747 }
5748 TString delim(" ");
5749 TObjArray* tokens = libs.Tokenize(delim);
5750 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5751 // convert "@@" to "::", we used "@@" because TEnv
5752 // considers "::" a terminator
5753 cls.Remove(0, 8);
5754 cls.ReplaceAll("@@", "::");
5755 // convert "-" to " ", since class names may have
5756 // blanks and TEnv considers a blank a terminator
5757 cls.ReplaceAll("-", " ");
5758 if (gDebug > 6) {
5759 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5760 if (wlib) {
5761 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5762 }
5763 else {
5764 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5765 }
5766 delete[] wlib;
5767 }
5768 delete tokens;
5769 }
5770 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5771 cls.Remove(0, 8);
5772 // convert "-" to " ", since class names may have
5773 // blanks and TEnv considers a blank a terminator
5774 cls.ReplaceAll("-", " ");
5775 fInterpreter->declare(cls.Data());
5776 }
5777 }
5778
5779 // Process the forward declarations collected
5780 cling::Transaction* T = nullptr;
5781 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5782 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5783
5784 if (compRes!=cling::Interpreter::kSuccess){
5785 Warning("LoadLibraryMap",
5786 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5787 }
5788
5789 if (T) {
5790 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5791 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5792 if (declIt->m_DGR.isSingleDecl()) {
5793 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5794 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5795 evsAdder.TraverseDecl(D);
5796 }
5797 }
5798 }
5799 }
5800 }
5801
5802 // clear duplicates
5803
5804 return 0;
5805}
5806
5807////////////////////////////////////////////////////////////////////////////////
5808/// Scan again along the dynamic path for library maps. Entries for the loaded
5809/// shared libraries are unloaded first. This can be useful after reseting
5810/// the dynamic path through TSystem::SetDynamicPath()
5811/// In case of error -1 is returned, 0 otherwise.
5812
5814{
5817 return 0;
5818}
5819
5820////////////////////////////////////////////////////////////////////////////////
5821/// Reload the library map entries coming from all the loaded shared libraries,
5822/// after first unloading the current ones.
5823/// In case of error -1 is returned, 0 otherwise.
5824
5826{
5827 const TString sharedLibLStr = GetSharedLibs();
5828 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5829 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5830 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5831 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5832 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5833 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5834 if (ret < 0) {
5835 continue;
5836 }
5837 TString rootMapBaseStr = sharedLibBaseStr;
5838 if (sharedLibBaseStr.EndsWith(".dll")) {
5839 rootMapBaseStr.ReplaceAll(".dll", "");
5840 }
5841 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5842 rootMapBaseStr.ReplaceAll(".DLL", "");
5843 }
5844 else if (sharedLibBaseStr.EndsWith(".so")) {
5845 rootMapBaseStr.ReplaceAll(".so", "");
5846 }
5847 else if (sharedLibBaseStr.EndsWith(".sl")) {
5848 rootMapBaseStr.ReplaceAll(".sl", "");
5849 }
5850 else if (sharedLibBaseStr.EndsWith(".dl")) {
5851 rootMapBaseStr.ReplaceAll(".dl", "");
5852 }
5853 else if (sharedLibBaseStr.EndsWith(".a")) {
5854 rootMapBaseStr.ReplaceAll(".a", "");
5855 }
5856 else {
5857 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5858 delete sharedLibL;
5859 return -1;
5860 }
5861 rootMapBaseStr += ".rootmap";
5862 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5863 if (!rootMap) {
5864 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5865 delete[] rootMap;
5866 delete sharedLibL;
5867 return -1;
5868 }
5869 const Int_t status = LoadLibraryMap(rootMap);
5870 if (status < 0) {
5871 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5872 delete[] rootMap;
5873 delete sharedLibL;
5874 return -1;
5875 }
5876 delete[] rootMap;
5877 }
5878 delete sharedLibL;
5879 return 0;
5880}
5881
5882////////////////////////////////////////////////////////////////////////////////
5883/// Unload the library map entries coming from all the loaded shared libraries.
5884/// Returns 0 if succesful
5885
5887{
5888 const TString sharedLibLStr = GetSharedLibs();
5889 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5890 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5891 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5892 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5893 UnloadLibraryMap(sharedLibBaseStr);
5894 }
5895 delete sharedLibL;
5896 return 0;
5897}
5898
5899////////////////////////////////////////////////////////////////////////////////
5900/// Unload library map entries coming from the specified library.
5901/// Returns -1 in case no entries for the specified library were found,
5902/// 0 otherwise.
5903
5905{
5906 if (!fMapfile || !library || !*library) {
5907 return 0;
5908 }
5909 TString libname(library);
5910 Ssiz_t idx = libname.Last('.');
5911 if (idx != kNPOS) {
5912 libname.Remove(idx);
5913 }
5914 size_t len = libname.Length();
5915 TEnvRec *rec;
5916 TIter next(fMapfile->GetTable());
5918 Int_t ret = 0;
5919 while ((rec = (TEnvRec *) next())) {
5920 TString cls = rec->GetName();
5921 if (cls.Length() > 2) {
5922 // get the first lib from the list of lib and dependent libs
5923 TString libs = rec->GetValue();
5924 if (libs == "") {
5925 continue;
5926 }
5927 TString delim(" ");
5928 TObjArray* tokens = libs.Tokenize(delim);
5929 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5930 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5931 // convert "@@" to "::", we used "@@" because TEnv
5932 // considers "::" a terminator
5933 cls.Remove(0, 8);
5934 cls.ReplaceAll("@@", "::");
5935 // convert "-" to " ", since class names may have
5936 // blanks and TEnv considers a blank a terminator
5937 cls.ReplaceAll("-", " ");
5938 }
5939 if (!strncmp(lib, libname.Data(), len)) {
5940 if (fMapfile->GetTable()->Remove(rec) == 0) {
5941 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
5942 ret = -1;
5943 }
5944 }
5945 delete tokens;
5946 }
5947 }
5948 if (ret >= 0) {
5949 TString library_rootmap(library);
5950 if (!library_rootmap.EndsWith(".rootmap"))
5951 library_rootmap.Append(".rootmap");
5952 TNamed* mfile = 0;
5953 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5954 fRootmapFiles->Remove(mfile);
5955 delete mfile;
5956 }
5958 }
5959 return ret;
5960}
5961
5962////////////////////////////////////////////////////////////////////////////////
5963/// Register the AutoLoading information for a class.
5964/// libs is a space separated list of libraries.
5965
5966Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
5967{
5968 if (!cls || !*cls)
5969 return 0;
5970
5971 TString key = TString("Library.") + cls;
5972 // convert "::" to "@@", we used "@@" because TEnv
5973 // considers "::" a terminator
5974 key.ReplaceAll("::", "@@");
5975 // convert "-" to " ", since class names may have
5976 // blanks and TEnv considers a blank a terminator
5977 key.ReplaceAll(" ", "-");
5978
5980 if (!fMapfile) {
5981 fMapfile = new TEnv();
5983
5986
5987 InitRootmapFile(".rootmap");
5988 }
5989 //fMapfile->SetValue(key, libs);
5990 fMapfile->SetValue(cls, libs);
5991 return 1;
5992}
5993
5994////////////////////////////////////////////////////////////////////////////////
5995/// Demangle the name (from the typeinfo) and then request the class
5996/// via the usual name based interface (TClass::GetClass).
5997
5998TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
5999{
6000 int err = 0;
6001 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6002 if (err) return 0;
6003 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6004 free(demangled_name);
6005 return theClass;
6006}
6007
6008////////////////////////////////////////////////////////////////////////////////
6009/// Load library containing the specified class. Returns 0 in case of error
6010/// and 1 in case if success.
6011
6012Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6013{
6014 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6015
6016 int err = 0;
6017 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6018 if (err) {
6019 return 0;
6020 }
6021
6022 std::string demangled_name(demangled_name_c);
6023 free(demangled_name_c);
6024
6025 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6026 // shortened name.
6028 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6029
6030 // No need to worry about typedef, they aren't any ... but there are
6031 // inlined namespaces ...
6032
6033 Int_t result = AutoLoad(demangled_name.c_str());
6034 if (result == 0) {
6035 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6036 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6037 }
6038
6039 return result;
6040}
6041
6042////////////////////////////////////////////////////////////////////////////////
6043// Get the list of 'published'/'known' library for the class and load them.
6045{
6046 Int_t status = 0;
6047
6048 // lookup class to find list of dependent libraries
6049 TString deplibs = gCling->GetClassSharedLibs(cls);
6050 if (!deplibs.IsNull()) {
6051 TString delim(" ");
6052 TObjArray* tokens = deplibs.Tokenize(delim);
6053 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6054 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6055 if (gROOT->LoadClass(cls, deplib) == 0) {
6056 if (gDebug > 0) {
6057 gCling->Info("TCling::AutoLoad",
6058 "loaded dependent library %s for %s", deplib, cls);
6059 }
6060 }
6061 else {
6062 gCling->Error("TCling::AutoLoad",
6063 "failure loading dependent library %s for %s",
6064 deplib, cls);
6065 }
6066 }
6067 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6068 if (lib && lib[0]) {
6069 if (gROOT->LoadClass(cls, lib) == 0) {
6070 if (gDebug > 0) {
6071 gCling->Info("TCling::AutoLoad",
6072 "loaded library %s for %s", lib, cls);
6073 }
6074 status = 1;
6075 }
6076 else {
6077 gCling->Error("TCling::AutoLoad",
6078 "failure loading library %s for %s", lib, cls);
6079 }
6080 }
6081 delete tokens;
6082 }
6083
6084 return status;
6085}
6086
6087////////////////////////////////////////////////////////////////////////////////
6088// Iterate through the data member of the class (either through the TProtoClass
6089// or through Cling) and trigger, recursively, the loading the necessary libraries.
6090// \note `cls` is expected to be already normalized!
6091// \returns 1 on success.
6092Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6093 bool nameIsNormalized)
6094{
6095 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6096 // has previously (within the same call to `AutoLoad()`) tried to load this class
6097 // and we are done, whether success or not, as it won't work better now than before,
6098 // because there is no additional information now compared to before.
6099 if (!visited.insert(std::string(cls)).second)
6100 return 1;
6101
6102 if (ShallowAutoLoadImpl(cls) == 0) {
6103 // If ShallowAutoLoadImpl() has an error, we have an error.
6104 return 0;
6105 }
6106
6107 // Now look through the TProtoClass to load the required library/dictionary
6108 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6109 for (auto element : proto->GetData()) {
6110 if (element->IsBasic())
6111 continue;
6112 const char *subtypename = element->GetTypeName();
6113 if (!TClassTable::GetDictNorm(subtypename)) {
6114 // Failure to load a dictionary is not (quite) a failure load
6115 // the top-level library. If we return false here, then
6116 // we would end up in a situation where the library and thus
6117 // the dictionary is loaded for "cls" but the TClass is
6118 // not created and/or marked as unavailable (in case where
6119 // AutoLoad is called from TClass::GetClass).
6120 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6121 }
6122 }
6123 return 1;
6124 }
6125
6126 // We found no TProtoClass for cls.
6127 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6128 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6129 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6130 {
6131 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6132 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6133 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6134 continue;
6135 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6136 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6137 // Failure to load a dictionary is not (quite) a failure load
6138 // the top-level library. See detailed comment in the TProtoClass
6139 // branch (above).
6140 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6141 }
6142 }
6143 gInterpreter->DataMemberInfo_Delete(memberinfo);
6144 }
6145 gInterpreter->ClassInfo_Delete(classinfo);
6146 return 1;
6147}
6148
6149////////////////////////////////////////////////////////////////////////////////
6150/// Load library containing the specified class. Returns 0 in case of error
6151/// and 1 in case if success.
6152
6153Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6154{
6155 // Prevent update to IsClassAutoloading between our check and our actions.
6157
6158 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6159 // rootcling (in *_rdict.pcm file generation) it is a no op.
6160 // FIXME: We should avoid calling autoload when we know we are not supposed
6161 // to and transform this check into an assert.
6163 // Never load any library from rootcling/genreflex.
6164 if (gDebug > 2) {
6165 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6166 }
6167 return 0;
6168 }
6169
6170 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6171
6173
6174 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6175 // The library is already loaded as the class's dictionary is known.
6176 // Return success.
6177 // Note: the name (cls) is expected to be normalized as it comes either
6178 // from a callbacks (that can/should calculate the normalized name from the
6179 // decl) or from TClass::GetClass (which does also calculate the normalized
6180 // name).
6181 return 1;
6182 }
6183
6184 if (gDebug > 2) {
6185 Info("TCling::AutoLoad",
6186 "Trying to autoload for %s", cls);
6187 }
6188
6189 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6190 if (gDebug > 2) {
6191 Info("TCling::AutoLoad",
6192 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6193 }
6194 return 0;
6195 }
6196 // Prevent the recursion when the library dictionary are loaded.
6197 SuspendAutoLoadingRAII autoLoadOff(this);
6198 // Try using externally provided callback first.
6199 if (fAutoLoadCallBack) {
6200 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6201 if (success)
6202 return success;
6203 }
6204
6205 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6206 // (when module are enabled) which might end up calling AutoParsing but
6207 // that should only be for the cases where the library has no generated pcm
6208 // and in that case a rootmap should be available.
6209 // This avoids a very costly operation (for generally no gain) but reduce the
6210 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6211 // file).
6212 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6213 std::unordered_set<std::string> visited;
6214 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6215}
6216
6217////////////////////////////////////////////////////////////////////////////////
6218/// Parse the payload or header.
6219
6220static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6221 Bool_t header,
6222 cling::Interpreter *interpreter)
6223{
6224 std::string code = gNonInterpreterClassDef ;
6225 if (!header) {
6226 // This is the complete header file content and not the
6227 // name of a header.
6228 code += what;
6229
6230 } else {
6231 code += ("#include \"");
6232 code += what;
6233 code += "\"\n";
6234 }
6235 code += ("#ifdef __ROOTCLING__\n"
6236 "#undef __ROOTCLING__\n"
6237 + gInterpreterClassDef +
6238 "#endif");
6239
6240 cling::Interpreter::CompilationResult cr;
6241 {
6242 // scope within which diagnostics are de-activated
6243 // For now we disable diagnostics because we saw them already at
6244 // dictionary generation time. That won't be an issue with the PCMs.
6245
6246 Sema &SemaR = interpreter->getSema();
6247 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6248 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6249
6250 #if defined(R__MUST_REVISIT)
6251 #if R__MUST_REVISIT(6,2)
6252 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6253 #endif
6254 #endif
6255
6256 cr = interpreter->parseForModule(code);
6257 }
6258 return cr;
6259}
6260
6261////////////////////////////////////////////////////////////////////////////////
6262/// Helper routine for TCling::AutoParse implementing the actual call to the
6263/// parser and looping over template parameters (if
6264/// any) and when they don't have a registered header to autoparse,
6265/// recurse over their template parameters.
6266///
6267/// Returns the number of header parsed.
6268
6269UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6270{
6271 // We assume the lock has already been taken.
6272 // R__LOCKGUARD(gInterpreterMutex);
6273
6274 Int_t nHheadersParsed = 0;
6275 unsigned long offset = 0;
6276 if (strncmp(cls, "const ", 6) == 0) {
6277 offset = 6;
6278 }
6279
6280 // Loop on the possible autoparse keys
6281 bool skipFirstEntry = false;
6282 std::vector<std::string> autoparseKeys;
6283 if (strchr(cls, '<')) {
6284 int nestedLoc = 0;
6285 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6286 // Check if we can skip the name of the template in the autoparses
6287 // Take all the scopes one by one. If all of them are in the AST, we do not
6288 // need to autoparse for that particular template.
6289 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6290 // autoparseKeys[0] is empty when the input is not a template instance.
6291 // The case strchr(cls, '<') != 0 but still not a template instance can
6292 // happens 'just' for string (GetSplit replaces the template by the short name
6293 // and then use that for thew splitting)
6294 TString templateName(autoparseKeys[0]);
6295 auto tokens = templateName.Tokenize("::");
6296 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6297 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6298 if (TClassEdit::IsStdClass(cls + offset))
6299 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6300 auto nTokens = tokens->GetEntriesFast();
6301 for (Int_t tk = 0; tk < nTokens; ++tk) {
6302 auto scopeObj = tokens->UncheckedAt(tk);
6303 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6304 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6305 // Check if we have multiple nodes in the AST with this name
6306 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6307 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6308 if (!previousScopeAsContext) break; // this is not a context
6309 }
6310 delete tokens;
6311 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6312 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6313 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6314 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6315 skipFirstEntry = templatedDecl->hasDefinition();
6316 }
6317 }
6318 }
6319
6320 }
6321 }
6322 if (topLevel) autoparseKeys.emplace_back(cls);
6323
6324 for (const auto & apKeyStr : autoparseKeys) {
6325 if (skipFirstEntry) {
6326 skipFirstEntry=false;
6327 continue;
6328 }
6329 if (apKeyStr.empty()) continue;
6330 const char *apKey = apKeyStr.c_str();
6331 std::size_t normNameHash(fStringHashFunction(apKey));
6332 // If the class was not looked up
6333 if (gDebug > 1) {
6334 Info("TCling::AutoParse",
6335 "Starting autoparse for %s\n", apKey);
6336 }
6337 if (fLookedUpClasses.insert(normNameHash).second) {
6338 auto const &iter = fClassesHeadersMap.find(normNameHash);
6339 if (iter != fClassesHeadersMap.end()) {
6340 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6341 fTransactionHeadersMap.insert({T,normNameHash});
6342 auto const &hNamesPtrs = iter->second;
6343 if (gDebug > 1) {
6344 Info("TCling::AutoParse",
6345 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6346 }
6347 for (auto & hName : hNamesPtrs) {
6348 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6349 if (0 != fPayloads.count(normNameHash)) {
6350 float initRSSval=0.f, initVSIZEval=0.f;
6351 (void) initRSSval; // Avoid unused var warning
6352 (void) initVSIZEval;
6353 if (gDebug > 0) {
6354 Info("AutoParse",
6355 "Parsing full payload for %s", apKey);
6356 ProcInfo_t info;
6357 gSystem->GetProcInfo(&info);
6358 initRSSval = 1e-3*info.fMemResident;
6359 initVSIZEval = 1e-3*info.fMemVirtual;
6360 }
6361 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6362 if (cRes != cling::Interpreter::kSuccess) {
6363 if (hName[0] == '\n')
6364 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6365 } else {
6366 fParsedPayloadsAddresses.insert(hName);
6367 nHheadersParsed++;
6368 if (gDebug > 0){
6369 ProcInfo_t info;
6370 gSystem->GetProcInfo(&info);
6371 float endRSSval = 1e-3*info.fMemResident;
6372 float endVSIZEval = 1e-3*info.fMemVirtual;
6373 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6374 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6375 }
6376 }
6377 } else if (!IsLoaded(hName)) {
6378 if (gDebug > 0) {
6379 Info("AutoParse",
6380 "Parsing single header %s", hName);
6381 }
6382 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6383 if (cRes != cling::Interpreter::kSuccess) {
6384 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6385 } else {
6386 nHheadersParsed++;
6387 }
6388 }
6389 }
6390 }
6391 else {
6392 // There is no header registered for this class, if this a
6393 // template, it will be instantiated if/when it is requested
6394 // and if we do no load/parse its components we might end up
6395 // not using an eventual specialization.
6396 if (strchr(apKey, '<')) {
6397 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6398 }
6399 }
6400 }
6401 }
6402
6403 return nHheadersParsed;
6404
6405}
6406
6407////////////////////////////////////////////////////////////////////////////////
6408/// Parse the headers relative to the class
6409/// Returns 1 in case of success, 0 in case of failure
6410
6411Int_t TCling::AutoParse(const char *cls)
6412{
6413 if (llvm::StringRef(cls).contains("(lambda)"))
6414 return 0;
6415
6418 return AutoLoad(cls);
6419 } else {
6420 return 0;
6421 }
6422 }
6423
6425
6426 if (gDebug > 1) {
6427 Info("TCling::AutoParse",
6428 "Trying to autoparse for %s", cls);
6429 }
6430
6431 // The catalogue of headers is in the dictionary
6433 && !gClassTable->GetDictNorm(cls)) {
6434 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6435 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6436 fInterpreter->getSema());
6437 AutoLoad(cls, true /*knowDictNotLoaded*/);
6438 }
6439
6440 // Prevent the recursion when the library dictionary are loaded.
6441 SuspendAutoLoadingRAII autoLoadOff(this);
6442
6443 // No recursive header parsing on demand; we require headers to be standalone.
6444 SuspendAutoParsing autoParseRAII(this);
6445
6446 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6447
6449
6450 return nHheadersParsed > 0 ? 1 : 0;
6451}
6452
6453// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6454// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6455// false if not.
6456bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6457{
6458 StringRef errMsg(errmessage);
6459 if (errMsg.contains("undefined symbol: ")) {
6460 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6461 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6462 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6463 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6464 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6465 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6466 return true;
6467 } else {
6468 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6469 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6470 return true;
6471 }
6472
6473 return false;
6474}
6475
6476static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
6477 const cling::DynamicLibraryManager &DLM) {
6479
6480 auto LibLoader = [](const std::string& LibName) -> bool {
6481 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6482 Error("TCling__LazyFunctionCreatorAutoloadForModule",
6483 "Failed to load library %s", LibName.c_str());
6484 return false;
6485 }
6486 return true; //success.
6487 };
6488
6489#ifdef R__MACOSX
6490 // The JIT gives us a mangled name which has only one leading underscore on
6491 // all platforms, for instance _ZN8TRandom34RndmEv. However, on OSX the
6492 // linker stores this symbol as __ZN8TRandom34RndmEv (adding an extra _).
6493 assert(!llvm::StringRef(mangled_name).startswith("__") && "Already added!");
6494 std::string libName = DLM.searchLibrariesForSymbol('_' + mangled_name,
6495 /*searchSystem=*/ true);
6496#else
6497 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6498 /*searchSystem=*/ true);
6499#endif //R__MACOSX
6500
6501 assert(!llvm::StringRef(libName).startswith("libNew") &&
6502 "We must not resolve symbols from libNew!");
6503
6504 if (libName.empty())
6505 return nullptr;
6506
6507 if (!LibLoader(libName))
6508 return nullptr;
6509
6510 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name);
6511
6512}
6513
6514////////////////////////////////////////////////////////////////////////////////
6515/// Autoload a library based on a missing symbol.
6516
6517void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6519 return LazyFunctionCreatorAutoloadForModule(mangled_name,
6520 *GetInterpreterImpl()->getDynamicLibraryManager());
6521
6522 // First see whether the symbol is in the library that we are currently
6523 // loading. It will have access to the symbols of its dependent libraries,
6524 // thus checking "back()" is sufficient.
6525 if (!fRegisterModuleDyLibs.empty()) {
6526 if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
6527 mangled_name.c_str())) {
6528 return addr;
6529 }
6530 }
6531
6532 int err = 0;
6533 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6534 if (err) {
6535 return 0;
6536 }
6537
6538 std::string name(demangled_name_c);
6539 free(demangled_name_c);
6540
6541 //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
6542 //
6543 // Separate out the class or namespace part of the
6544 // function name.
6545 //
6546
6547 std::string::size_type pos = name.find("__thiscall ");
6548 if (pos != std::string::npos) {
6549 name.erase(0, pos + sizeof("__thiscall ")-1);
6550 }
6551 pos = name.find("__cdecl ");
6552 if (pos != std::string::npos) {
6553 name.erase(0, pos + sizeof("__cdecl ")-1);
6554 }
6555 if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
6556 name.erase(0, sizeof("typeinfo for ")-1);
6557 } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
6558 name.erase(0, sizeof("vtable for ")-1);
6559 } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
6560 && !isalnum(name[sizeof("operator")])) {
6561 // operator...(A, B) - let's try with A!
6562 name.erase(0, sizeof("operator")-1);
6563 pos = name.rfind('(');
6564 if (pos != std::string::npos) {
6565 name.erase(0, pos + 1);
6566 pos = name.find(",");
6567 if (pos != std::string::npos) {
6568 // remove next arg up to end, leaving only the first argument type.
6569 name.erase(pos);
6570 }
6571 pos = name.rfind(" const");
6572 if (pos != std::string::npos) {
6573 name.erase(pos, strlen(" const"));
6574 }
6575 while (!name.empty() && strchr("&*", name.back()))
6576 name.erase(name.length() - 1);
6577 }
6578 } else {
6581 name = fsi.fScopeName;
6582 }
6583 //fprintf(stderr, "name: '%s'\n", name.c_str());
6584 // Now we have the class or namespace name, so do the lookup.
6585 TString libs = GetClassSharedLibs(name.c_str());
6586 if (libs.IsNull()) {
6587 // Not found in the map, all done.
6588 return 0;
6589 }
6590 //fprintf(stderr, "library: %s\n", iter->second.c_str());
6591 // Now we have the name of the libraries to load, so load them.
6592
6593 TString lib;
6594 Ssiz_t posLib = 0;
6595 while (libs.Tokenize(lib, posLib)) {
6596 if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
6597 // The library load failed, all done.
6598 //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
6599 return 0;
6600 }
6601 }
6602
6603 //fprintf(stderr, "load succeeded.\n");
6604 // Get the address of the function being called.
6605 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6606 //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
6607 return addr;
6608}
6609
6610////////////////////////////////////////////////////////////////////////////////
6611
6612Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6613{
6614 return fNSFromRootmaps.count(nsDecl) != 0;
6615}
6616
6617////////////////////////////////////////////////////////////////////////////////
6618/// Internal function. Actually do the update of the ClassInfo when seeing
6619// new TagDecl or NamespaceDecl.
6620void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6621{
6622
6624 if (cci) {
6625 // If we only had a forward declaration then update the
6626 // TClingClassInfo with the definition if we have it now.
6627 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6628 if (!oldDef || (def && def != oldDef)) {
6629 cl->ResetCaches();
6631 if (def) {
6632 // It's a tag decl, not a namespace decl.
6633 cci->Init(*cci->GetType());
6635 }
6636 }
6637 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6638 cl->ResetCaches();
6639 // yes, this is almost a waste of time, but we do need to lookup
6640 // the 'type' corresponding to the TClass anyway in order to
6641 // preserve the opaque typedefs (Double32_t)
6642 if (!alias && def != nullptr)
6643 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6644 else
6645 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6646 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6647 // We now need to update the state and bits.
6648 if (cl->fState != TClass::kHasTClassInit) {
6649 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6652 }
6653 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6654 } else {
6655 delete ((TClingClassInfo *)cl->fClassInfo);
6656 cl->fClassInfo = nullptr;
6657 }
6658 }
6659}
6660
6661////////////////////////////////////////////////////////////////////////////////
6662/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6663void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6664{
6665 const TagDecl *td = dyn_cast<TagDecl>(ND);
6666 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6667 const NamedDecl *canon = nullptr;
6668
6669 std::string name;
6670 TagDecl* tdDef = 0;
6671 if (td) {
6672 canon = tdDef = td->getDefinition();
6673 // Let's pass the decl to the TClass only if it has a definition.
6674 if (!tdDef) return;
6675
6676 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6677 // Ignore incomplete definition.
6678 // Ignore declaration within a function.
6679 return;
6680 }
6681
6682 auto declName = tdDef->getNameAsString();
6683 // Check if we have registered the unqualified name into the list
6684 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6685 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6686 // the unqualified name is sufficient (and the fully qualified name might be
6687 // 'wrong' if there is difference in spelling in the template paramters (for example)
6688 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6689 // 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() );
6690 return;
6691 }
6692
6693 clang::QualType type(tdDef->getTypeForDecl(), 0);
6695 } else if (ns) {
6696 canon = ns->getCanonicalDecl();
6697 name = ND->getQualifiedNameAsString();
6698 } else {
6699 name = ND->getQualifiedNameAsString();
6700 }
6701
6702 // Supposedly we are being called while something is being
6703 // loaded ... let's now tell the autoloader to do the work
6704 // yet another time.
6705 SuspendAutoLoadingRAII autoLoadOff(this);
6706 // FIXME: There can be more than one TClass for a single decl.
6707 // for example vector<double> and vector<Double32_t>
6708 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6709 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6710 RefreshClassInfo(cl, canon, false);
6711 }
6712 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6713 // and update them too:
6714 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6715 // RefreshClassInfo(cl, tdDef, true);
6716}
6717
6718////////////////////////////////////////////////////////////////////////////////
6719/// No op: see TClingCallbacks
6720
6721void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6722{
6723}
6724
6725//______________________________________________________________________________
6726//FIXME: Factor out that function in TClass, because TClass does it already twice
6727void TCling::UpdateClassInfoWork(const char* item)
6728{
6729 // This is a no-op as part of the API.
6730 // TCling uses UpdateClassInfoWithDecl() instead.
6731}
6732
6733////////////////////////////////////////////////////////////////////////////////
6734/// Update all canvases at end the terminal input command.
6735
6737{
6738 TIter next(gROOT->GetListOfCanvases());
6739 TVirtualPad* canvas;
6740 while ((canvas = (TVirtualPad*)next())) {
6741 canvas->Update();
6742 }
6743}
6744
6745////////////////////////////////////////////////////////////////////////////////
6746
6747void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6748 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6749
6750 // If the transaction does not contain anything we can return earlier.
6751 if (!HandleNewTransaction(T)) return;
6752
6753 bool isTUTransaction = false;
6754 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6755 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6756 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6757 // The is the first transaction, we have to expose to meta
6758 // what's already in the AST.
6759 isTUTransaction = true;
6760 }
6761 }
6762
6763 std::set<const void*> TransactionDeclSet;
6764 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6765 const clang::Decl* WrapperFD = T.getWrapperFD();
6766 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6767 I != E; ++I) {
6768 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6769 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6770 continue;
6771
6772 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6773 DE = I->m_DGR.end(); DI != DE; ++DI) {
6774 if (*DI == WrapperFD)
6775 continue;
6776 TransactionDeclSet.insert(*DI);
6777 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6778 }
6779 }
6780 }
6781
6782 // The above might trigger more decls to be deserialized.
6783 // Thus the iteration over the deserialized decls must be last.
6784 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6785 E = T.deserialized_decls_end(); I != E; ++I) {
6786 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6787 DE = I->m_DGR.end(); DI != DE; ++DI)
6788 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6789 //FIXME: HandleNewDecl should take DeclGroupRef
6790 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6791 modifiedTClasses);
6792 }
6793 }
6794
6795
6796 // When fully building the reflection info in TClass, a deserialization
6797 // could be triggered, which may result in request for building the
6798 // reflection info for the same TClass. This in turn will clear the caches
6799 // for the TClass in-flight and cause null ptr derefs.
6800 // FIXME: This is a quick fix, solving most of the issues. The actual
6801 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6802 // itself until the update is done.
6803 //
6804 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6805 std::vector<TClass*>::iterator it;
6806 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6807 ((TCling*)gCling)->GetModTClasses().begin(),
6808 ((TCling*)gCling)->GetModTClasses().end(),
6809 modifiedTClassesDiff.begin());
6810 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6811
6812 // Lock the TClass for updates
6813 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6814 modifiedTClassesDiff.end());
6815 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6816 E = modifiedTClassesDiff.end(); I != E; ++I) {
6817 // Make sure the TClass has not been deleted.
6818 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6819 continue;
6820 }
6821 // Could trigger deserialization of decls.
6822 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6823 // Unlock the TClass for updates
6824 ((TCling*)gCling)->GetModTClasses().erase(*I);
6825
6826 }
6827}
6828
6829///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6830///
6831void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6832{
6834
6835 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6836 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6837 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6838 (TListOfEnums *)gROOT->GetListOfEnums());
6839
6840 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6841 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6842 I != E; ++I) {
6843 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6844 continue;
6845 if (I->m_Call == cling::Transaction::kCCINone) {
6846 UpdateListsOnUnloaded(*(*iNested));
6847 ++iNested;
6848 continue;
6849 }
6850
6851 for (auto &D : I->m_DGR)
6852 InvalidateCachedDecl(Lists, D);
6853 }
6854}
6855
6856///\brief Invalidate cached TCling information for the given global declaration.
6857///
6858void TCling::InvalidateGlobal(const Decl *D) {
6859 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6860 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6861 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6862 (TListOfEnums *)gROOT->GetListOfEnums());
6863 InvalidateCachedDecl(Lists, D);
6864}
6865
6866///\brief Invalidate cached TCling information for the given declaration, and
6867/// removed it from the appropriate object list.
6868///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6869/// TListOfFunctionTemplates&, TListOfEnums&>
6870/// of pointers to the (global/class) object lists.
6871///\param[in] D - Decl to discard.
6872///
6876 TListOfEnums*> &Lists, const Decl *D) {
6877 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6878 return;
6879
6880 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6881 TListOfFunctions &LOF = *(std::get<1>(Lists));
6882 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6883 TListOfEnums &LOE = *(std::get<3>(Lists));
6884
6885 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6886 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6887 if (LODM.GetClass())
6888 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6889 else
6890 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6891 } else if (isa<FunctionDecl>(D)) {
6893 } else if (isa<FunctionTemplateDecl>(D)) {
6895 } else if (isa<EnumDecl>(D)) {
6896 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6897 if (!E)
6898 return;
6899
6900 // Try to invalidate enumerators (for unscoped enumerations).
6901 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6903 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6904
6906 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6907 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6908 return;
6909
6910 std::vector<TClass *> Classes;
6911 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6912 return;
6913 for (auto &C : Classes) {
6914 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6915 (TListOfFunctions *)C->GetListOfMethods(),
6916 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6917 (TListOfEnums *)C->GetListOfEnums());
6918 for (auto &I : cast<DeclContext>(D)->decls())
6919 InvalidateCachedDecl(Lists, I);
6920
6921 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6922 if (D->getKind() != Decl::Namespace
6923 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6924 C->ResetClassInfo();
6925 }
6926 }
6927}
6928
6929////////////////////////////////////////////////////////////////////////////////
6930// If an autoparse was done during a transaction and that it is rolled back,
6931// we need to make sure the next request for the same autoparse will be
6932// honored.
6933void TCling::TransactionRollback(const cling::Transaction &T) {
6934 auto const &triter = fTransactionHeadersMap.find(&T);
6935 if (triter != fTransactionHeadersMap.end()) {
6936 std::size_t normNameHash = triter->second;
6937
6938 fLookedUpClasses.erase(normNameHash);
6939
6940 auto const &iter = fClassesHeadersMap.find(normNameHash);
6941 if (iter != fClassesHeadersMap.end()) {
6942 auto const &hNamesPtrs = iter->second;
6943 for (auto &hName : hNamesPtrs) {
6944 if (gDebug > 0) {
6945 Info("TransactionRollback",
6946 "Restoring ability to autoaparse: %s", hName);
6947 }
6948 fParsedPayloadsAddresses.erase(hName);
6949 }
6950 }
6951 }
6952}
6953
6954////////////////////////////////////////////////////////////////////////////////
6955
6956void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6957// R__LOCKGUARD_CLING(gInterpreterMutex);
6958// UpdateListOfLoadedSharedLibraries();
6959}
6960
6961////////////////////////////////////////////////////////////////////////////////
6962
6963void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6965 fSharedLibs = "";
6966}
6967
6968////////////////////////////////////////////////////////////////////////////////
6969/// Return the list of shared libraries loaded into the process.
6970
6972{
6975 return fSharedLibs;
6976}
6977
6978static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6979{
6980 if (!cls || !*cls)
6981 return {};
6982
6983 using namespace clang;
6984 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6985 /*type*/ nullptr, /*instantiate*/ false)) {
6986 if (!D->isFromASTFile()) {
6987 if (gDebug > 5)
6988 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6989 return {};
6990 }
6991 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6992 llvm::DenseSet<Module *> &m_TopLevelModules;
6993
6994 public:
6995 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6996 void Collect(const Decl *D) { Visit(D); }
6997
6998 void VisitDecl(const Decl *D)
6999 {
7000 // FIXME: Such case is described ROOT-7765 where
7001 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7002 // They are specified as #includes in the LinkDef file. This leads to
7003 // generation of incomplete modulemap files and this logic fails to
7004 // compute the corresponding module of D.
7005 // FIXME: If we want to support such a case, we should not rely on
7006 // the contents of the modulemap but mangle D and look it up in the
7007 // .so files.
7008 if (!D->hasOwningModule())
7009 return;
7010 if (Module *M = D->getOwningModule()->getTopLevelModule())
7011 m_TopLevelModules.insert(M);
7012 }
7013
7014 void VisitTemplateArgument(const TemplateArgument &TA)
7015 {
7016 switch (TA.getKind()) {
7017 case TemplateArgument::Null:
7018 case TemplateArgument::Integral:
7019 case TemplateArgument::Pack:
7020 case TemplateArgument::NullPtr:
7021 case TemplateArgument::Expression:
7022 case TemplateArgument::Template:
7023 case TemplateArgument::TemplateExpansion: return;
7024 case TemplateArgument::Type:
7025 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7026 return Visit(TagTy->getDecl());
7027 return;
7028 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7029 }
7030 llvm_unreachable("Invalid TemplateArgument::Kind!");
7031 }
7032
7033 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7034 {
7035 if (CTSD->getOwningModule())
7036 VisitDecl(CTSD);
7037 else
7038 VisitDecl(CTSD->getSpecializedTemplate());
7039 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7040 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7041 VisitTemplateArgument(*Arg);
7042 }
7043 }
7044 };
7045
7046 llvm::DenseSet<Module *> TopLevelModules;
7047 ModuleCollector m(TopLevelModules);
7048 m.Collect(D);
7049 std::string result;
7050 for (auto M : TopLevelModules) {
7051 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7052 // link declaration.
7053 if (!M->LinkLibraries.size())
7054 continue;
7055 // We have preloaded the Core module thus libCore.so
7056 if (M->Name == "Core")
7057 continue;
7058 assert(M->LinkLibraries.size() == 1);
7059 if (!result.empty())
7060 result += ' ';
7061 result += M->LinkLibraries[0].Library;
7062 }
7063 return result;
7064 }
7065 return {};
7066}
7067
7068////////////////////////////////////////////////////////////////////////////////
7069/// Get the list of shared libraries containing the code for class cls.
7070/// The first library in the list is the one containing the class, the
7071/// others are the libraries the first one depends on. Returns 0
7072/// in case the library is not found.
7073
7074const char* TCling::GetClassSharedLibs(const char* cls)
7075{
7076 if (fCxxModulesEnabled) {
7077 llvm::StringRef className = cls;
7078 // If we get a class name containing lambda, we cannot parse it and we
7079 // can exit early.
7080 // FIXME: This works around a bug when we are instantiating a template
7081 // make_unique and the substitution fails. Seen in most of the dataframe
7082 // tests.
7083 if (className.contains("(lambda)"))
7084 return nullptr;
7085 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7086 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7087 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7088 std::string libs = GetClassSharedLibsForModule(cls, LH);
7089 if (!libs.empty()) {
7090 fAutoLoadLibStorage.push_back(libs);
7091 return fAutoLoadLibStorage.back().c_str();
7092 }
7093 }
7094
7095 if (!cls || !*cls) {
7096 return 0;
7097 }
7098 // lookup class to find list of libraries
7099 if (fMapfile) {
7100 TEnvRec* libs_record = 0;
7101 libs_record = fMapfile->Lookup(cls);
7102 if (libs_record) {
7103 const char* libs = libs_record->GetValue();
7104 return (*libs) ? libs : 0;
7105 }
7106 else {
7107 // Try the old format...
7108 TString c = TString("Library.") + cls;
7109 // convert "::" to "@@", we used "@@" because TEnv
7110 // considers "::" a terminator
7111 c.ReplaceAll("::", "@@");
7112 // convert "-" to " ", since class names may have
7113 // blanks and TEnv considers a blank a terminator
7114 c.ReplaceAll(" ", "-");
7115 // Use TEnv::Lookup here as the rootmap file must start with Library.
7116 // and do not support using any stars (so we do not need to waste time
7117 // with the search made by TEnv::GetValue).
7118 TEnvRec* libs_record = 0;
7119 libs_record = fMapfile->Lookup(c);
7120 if (libs_record) {
7121 const char* libs = libs_record->GetValue();
7122 return (*libs) ? libs : 0;
7123 }
7124 }
7125 }
7126 return 0;
7127}
7128
7129/// This interface returns a list of dependent libraries in the form:
7130/// lib libA.so libB.so libC.so. The first library is the library we are
7131/// searching dependencies for.
7132/// Note: In order to speed up the search, we display the dependencies of the
7133/// libraries which are not yet loaded. For instance, if libB.so was already
7134/// loaded the list would contain: lib libA.so libC.so.
7135static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7136 cling::Interpreter *interp,
7137 bool skipLoadedLibs = true)
7138{
7139 TString LibFullPath(lib);
7140 if (!llvm::sys::path::is_absolute(lib)) {
7141 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7142 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7143 return "";
7144 }
7145 } else {
7146 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7147 lib = llvm::sys::path::filename(lib);
7148 }
7149
7150 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7151 if (!ObjF) {
7152 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7153 return "";
7154 }
7155
7156 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7157
7158 std::set<string> DedupSet;
7159 std::string Result = lib + ' ';
7160 for (const auto &S : BinObjFile->symbols()) {
7161 uint32_t Flags = S.getFlags();
7162 if (Flags & llvm::object::SymbolRef::SF_Undefined) {
7163 llvm::Expected<StringRef> SymNameErr = S.getName();
7164 if (!SymNameErr) {
7165 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7166 continue;
7167 }
7168 llvm::StringRef SymName = SymNameErr.get();
7169 if (SymName.empty())
7170 continue;
7171
7172 if (BinObjFile->isELF()) {
7173 // Skip the symbols which are part of the C/C++ runtime and have a
7174 // fixed library version. See binutils ld VERSION. Those reside in
7175 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7176 if (SymName.contains("@@GLIBCXX") || SymName.contains("@@CXXABI") ||
7177 SymName.contains("@@GLIBC") || SymName.contains("@@GCC"))
7178 continue;
7179
7180 // Those are 'weak undefined' symbols produced by gcc. We can
7181 // ignore them.
7182 // FIXME: It is unclear whether we can ignore all weak undefined
7183 // symbols:
7184 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7185 if (SymName == "_Jv_RegisterClasses" ||
7186 SymName == "_ITM_deregisterTMCloneTable" ||
7187 SymName == "_ITM_registerTMCloneTable")
7188 continue;
7189 }
7190
7191// FIXME: this might really depend on MachO library format instead of R__MACOSX.
7192#ifdef R__MACOSX
7193 // MacOS symbols sometimes have an extra "_", see
7194 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
7195 if (skipLoadedLibs && SymName[0] == '_'
7196 && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName.drop_front()))
7197 continue;
7198#endif
7199
7200 // If we can find the address of the symbol, we have loaded it. Skip.
7201 if (skipLoadedLibs && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName))
7202 continue;
7203
7205 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7206 // The expected output is just filename without the full path, which
7207 // is not very accurate, because our Dyld implementation might find
7208 // a match in location a/b/c.so and if we return just c.so ROOT might
7209 // resolve it to y/z/c.so and there we might not be ABI compatible.
7210 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7211 if (!found.empty()) {
7212 std::string cand = llvm::sys::path::filename(found).str();
7213 if (!DedupSet.insert(cand).second)
7214 continue;
7215
7216 Result += cand + ' ';
7217 }
7218 }
7219 }
7220
7221 return Result;
7222}
7223
7224static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7225{
7226 // Check if we have parsed a rootmap file.
7227 llvm::SmallString<256> rootmapName;
7228 if (!lib.startswith("lib"))
7229 rootmapName.append("lib");
7230
7231 rootmapName.append(llvm::sys::path::filename(lib));
7232 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7233
7234 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7235 return true;
7236
7237 // Perform a last resort by dropping the lib prefix.
7238 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7239 if (rootmapNameNoLib.consume_front("lib"))
7240 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7241
7242 return false;
7243}
7244
7245static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7246{
7247 if (gCling->HasPCMForLibrary(lib.data()))
7248 return true;
7249
7250 return hasParsedRootmapForLibrary(lib);
7251}
7252
7253////////////////////////////////////////////////////////////////////////////////
7254/// Get the list a libraries on which the specified lib depends. The
7255/// returned string contains as first element the lib itself.
7256/// Returns 0 in case the lib does not exist or does not have
7257/// any dependencies. If useDyld is true, we iterate through all available
7258/// libraries and try to construct the dependency chain by resolving each
7259/// symbol.
7260
7261const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7262{
7263 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7264 return nullptr;
7265
7266 if (!hasParsedRootmapForLibrary(lib)) {
7267 llvm::SmallString<512> rootmapName(lib);
7268 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7269 if (llvm::sys::fs::exists(rootmapName)) {
7270 if (gDebug > 0)
7271 Info("Load", "loading %s", rootmapName.c_str());
7272 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7273 }
7274 }
7275
7276 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7277 if (gDebug > 0)
7278 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7279 }
7280
7281 if (useDyld) {
7282 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7283 if (!libs.empty()) {
7284 fAutoLoadLibStorage.push_back(libs);
7285 return fAutoLoadLibStorage.back().c_str();
7286 }
7287 }
7288
7289 if (!fMapfile || !lib || !lib[0]) {
7290 return 0;
7291 }
7292 TString libname(lib);
7293 Ssiz_t idx = libname.Last('.');
7294 if (idx != kNPOS) {
7295 libname.Remove(idx);
7296 }
7297 TEnvRec* rec;
7298 TIter next(fMapfile->GetTable());
7299 size_t len = libname.Length();
7300 while ((rec = (TEnvRec*) next())) {
7301 const char* libs = rec->GetValue();
7302 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7303 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7304 return libs;
7305 }
7306 }
7307 return 0;
7308}
7309
7310////////////////////////////////////////////////////////////////////////////////
7311/// If error messages are disabled, the interpreter should suppress its
7312/// failures and warning messages from stdout.
7313
7315{
7316#if defined(R__MUST_REVISIT)
7317#if R__MUST_REVISIT(6,2)
7318 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7319#endif
7320#endif
7321 return kTRUE;
7322}
7323
7324////////////////////////////////////////////////////////////////////////////////
7325/// If error messages are disabled, the interpreter should suppress its
7326/// failures and warning messages from stdout. Return the previous state.
7327
7329{
7330#if defined(R__MUST_REVISIT)
7331#if R__MUST_REVISIT(6,2)
7332 Warning("SetErrorMessages", "Interface not available yet.");
7333#endif
7334#endif
7336}
7337
7338////////////////////////////////////////////////////////////////////////////////
7339/// Refresh the list of include paths known to the interpreter and return it
7340/// with -I prepended.
7341
7343{
7345
7346 fIncludePath = "";
7347
7348 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7349 //false - no system header, true - with flags.
7350 fInterpreter->GetIncludePaths(includePaths, false, true);
7351 if (const size_t nPaths = includePaths.size()) {
7352 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7353
7354 for (size_t i = 0; i < nPaths; i += 2) {
7355 if (i)
7356 fIncludePath.Append(' ');
7357 fIncludePath.Append(includePaths[i].c_str());
7358
7359 if (includePaths[i] != "-I")
7360 fIncludePath.Append(' ');
7361 fIncludePath.Append('"');
7362 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7363 fIncludePath.Append('"');
7364 }
7365 }
7366
7367 return fIncludePath;
7368}
7369
7370////////////////////////////////////////////////////////////////////////////////
7371/// Return the directory containing CINT's stl cintdlls.
7372
7373const char* TCling::GetSTLIncludePath() const
7374{
7375 return "";
7376}
7377
7378//______________________________________________________________________________
7379// M I S C
7380//______________________________________________________________________________
7381
7382int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7383{
7384 // Interface to cling function
7385 return 0;
7386}
7387
7388////////////////////////////////////////////////////////////////////////////////
7389/// Interface to cling function
7390
7391int TCling::DisplayIncludePath(FILE *fout) const
7392{
7393 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
7394
7395 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7396 //false - no system header, true - with flags.
7397 fInterpreter->GetIncludePaths(includePaths, false, true);
7398 if (const size_t nPaths = includePaths.size()) {
7399 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7400
7401 std::string allIncludes("include path:");
7402 for (size_t i = 0; i < nPaths; i += 2) {
7403 allIncludes += ' ';
7404 allIncludes += includePaths[i];
7405
7406 if (includePaths[i] != "-I")
7407 allIncludes += ' ';
7408 allIncludes += includePaths[i + 1];
7409 }
7410
7411 fprintf(fout, "%s\n", allIncludes.c_str());
7412 }
7413
7414 return 0;
7415}
7416
7417////////////////////////////////////////////////////////////////////////////////
7418/// Interface to cling function
7419
7420void* TCling::FindSym(const char* entry) const
7421{
7422 return fInterpreter->getAddressOfGlobal(entry);
7423}
7424
7425////////////////////////////////////////////////////////////////////////////////
7426/// Let the interpreter issue a generic error, and set its error state.
7427
7428void TCling::GenericError(const char* error) const
7429{
7430#if defined(R__MUST_REVISIT)
7431#if R__MUST_REVISIT(6,2)
7432 Warning("GenericError","Interface not available yet.");
7433#endif
7434#endif
7435}
7436
7437////////////////////////////////////////////////////////////////////////////////
7438/// This routines used to return the address of the internal wrapper
7439/// function (of the interpreter) that was used to call *all* the
7440/// interpreted functions that were bytecode compiled (no longer
7441/// interpreted line by line). In Cling, there is no such
7442/// wrapper function.
7443/// In practice this routines was use to decipher whether the
7444/// pointer returns by InterfaceMethod could be used to uniquely
7445/// represent the function. In Cling if the function is in a
7446/// useable state (its compiled version is available), this is
7447/// always the case.
7448/// See TClass::GetMethod.
7449
7451{
7452 return 0;
7453}
7454
7455////////////////////////////////////////////////////////////////////////////////
7456/// Interface to cling function
7457
7459{
7460#if defined(R__MUST_REVISIT)
7461#if R__MUST_REVISIT(6,2)
7462 Warning("GetSecurityError", "Interface not available yet.");
7463#endif
7464#endif
7465 return 0;
7466}
7467
7468////////////////////////////////////////////////////////////////////////////////
7469/// Load a source file or library called path into the interpreter.
7470
7471int TCling::LoadFile(const char* path) const
7472{
7473 cling::Interpreter::CompilationResult compRes;
7474 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7475 return compRes == cling::Interpreter::kFailure;
7476}
7477
7478////////////////////////////////////////////////////////////////////////////////
7479/// Load the declarations from text into the interpreter.
7480/// Note that this cannot be (top level) statements; text must contain
7481/// top level declarations.
7482/// Returns true on success, false on failure.
7483
7484Bool_t TCling::LoadText(const char* text) const
7485{
7486 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7487}
7488
7489////////////////////////////////////////////////////////////////////////////////
7490/// Interface to cling function
7491
7492const char* TCling::MapCppName(const char* name) const
7493{
7494 TTHREAD_TLS_DECL(std::string,buffer);
7496 return buffer.c_str();
7497}
7498
7499////////////////////////////////////////////////////////////////////////////////
7500/// [Place holder for Mutex Lock]
7501/// Provide the interpreter with a way to
7502/// acquire a lock used to protect critical section
7503/// of its code (non-thread safe parts).
7504
7505void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7506{
7507 // nothing to do for now.
7508}
7509
7510////////////////////////////////////////////////////////////////////////////////
7511/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7512/// release a lock used to protect critical section
7513/// of its code (non-thread safe parts).
7514
7515void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7516{
7517 // nothing to do for now.
7518}
7519
7520////////////////////////////////////////////////////////////////////////////////
7521/// Returns if class AutoLoading is currently enabled.
7522
7524{
7525 if (IsFromRootCling())
7526 return false;
7527 if (!fClingCallbacks)
7528 return false;
7530}
7531
7532////////////////////////////////////////////////////////////////////////////////
7533/// Enable/Disable the AutoLoading of libraries.
7534/// Returns the old value, i.e whether it was enabled or not.
7535
7536int TCling::SetClassAutoLoading(int autoload) const
7537{
7538 // If no state change is required, exit early.
7539 // FIXME: In future we probably want to complain if we made a request which
7540 // was with the same state as before in order to catch programming errors.
7541 if ((bool) autoload == IsClassAutoLoadingEnabled())
7542 return autoload;
7543
7544 assert(fClingCallbacks && "We must have callbacks!");
7545 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7547 return oldVal;
7548}
7549
7550////////////////////////////////////////////////////////////////////////////////
7551/// Enable/Disable the Autoparsing of headers.
7552/// Returns the old value, i.e whether it was enabled or not.
7553
7555{
7556 bool oldVal = fHeaderParsingOnDemand;
7557 fHeaderParsingOnDemand = autoparse;
7558 return oldVal;
7559}
7560
7561////////////////////////////////////////////////////////////////////////////////
7562/// Suspend the Autoparsing of headers.
7563/// Returns the old value, i.e whether it was suspended or not.
7564
7569 return old;
7570}
7571
7572////////////////////////////////////////////////////////////////////////////////
7573/// Set a callback to receive error messages.
7574
7575void TCling::SetErrmsgcallback(void* p) const
7576{
7577#if defined(R__MUST_REVISIT)
7578#if R__MUST_REVISIT(6,2)
7579 Warning("SetErrmsgcallback", "Interface not available yet.");
7580#endif
7581#endif
7582}
7583
7585{
7586 if (enable) {
7587 auto consumer = new TClingDelegateDiagnosticPrinter(
7588 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7589 fInterpreter->getCI()->getLangOpts(),
7590 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7591 if (Level == clang::DiagnosticsEngine::Warning) {
7592 ::Warning("cling", "%s", Info.c_str());
7593 } else if (Level == clang::DiagnosticsEngine::Error
7594 || Level == clang::DiagnosticsEngine::Fatal) {
7595 ::Error("cling", "%s", Info.c_str());
7596 } else {
7597 ::Info("cling", "%s", Info.c_str());
7598 }
7599 });
7600 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7601 } else {
7602 fInterpreter->replaceDiagnosticConsumer(nullptr);
7603 }
7604}
7605
7606
7607////////////////////////////////////////////////////////////////////////////////
7608/// Create / close a scope for temporaries. No-op for cling; use
7609/// cling::Value instead.
7610
7611void TCling::SetTempLevel(int val) const
7612{
7613}
7614
7615////////////////////////////////////////////////////////////////////////////////
7616
7617int TCling::UnloadFile(const char* path) const
7618{
7619 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7620 std::string canonical = DLM->lookupLibrary(path);
7621 if (canonical.empty()) {
7622 canonical = path;
7623 }
7624 // Unload a shared library or a source file.
7625 cling::Interpreter::CompilationResult compRes;
7626 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7627 return compRes == cling::Interpreter::kFailure;
7628}
7629
7630std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7631 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7632}
7633
7634////////////////////////////////////////////////////////////////////////////////
7635/// The call to Cling's tab complition.
7636
7637void TCling::CodeComplete(const std::string& line, size_t& cursor,
7638 std::vector<std::string>& completions)
7639{
7640 fInterpreter->codeComplete(line, cursor, completions);
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644/// Get the interpreter value corresponding to the statement.
7645int TCling::Evaluate(const char* code, TInterpreterValue& value)
7646{
7647 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7648 auto compRes = fInterpreter->evaluate(code, *V);
7649 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7650}
7651
7652////////////////////////////////////////////////////////////////////////////////
7653
7655{
7656 using namespace cling;
7657 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7659}
7660
7661////////////////////////////////////////////////////////////////////////////////
7662/// Register value as a temporary, extending its lifetime to that of the
7663/// interpreter. This is needed for TCling's compatibility interfaces
7664/// returning long - the address of the temporary objects.
7665/// As such, "simple" types don't need to be stored; they are returned by
7666/// value; only pointers / references / objects need to be stored.
7667
7668void TCling::RegisterTemporary(const cling::Value& value)
7669{
7670 if (value.isValid() && value.needsManagedAllocation()) {
7672 fTemporaries->push_back(value);
7673 }
7674}
7675
7676////////////////////////////////////////////////////////////////////////////////
7677/// If the interpreter encounters Name, check whether that is an object ROOT
7678/// could retrieve. To not re-read objects from disk, cache the name/object
7679/// pair for a given LookupCtx.
7680
7681TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7682{
7683 // The call to FindSpecialObject might induces any kind of use
7684 // of the interpreter ... (library loading, function calling, etc.)
7685 // ... and we _know_ we are in the middle of parsing, so let's make
7686 // sure to save the state and then restore it.
7687
7688 if (gDirectory) {
7689 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7690 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7691 auto iSpecObj = iSpecObjMap->second.find(Name);
7692 if (iSpecObj != iSpecObjMap->second.end()) {
7693 LookupCtx = gDirectory;
7694 return iSpecObj->second;
7695 }
7696 }
7697 }
7698
7699 // Save state of the PP
7700 Sema &SemaR = fInterpreter->getSema();
7701 ASTContext& C = SemaR.getASTContext();
7702 Preprocessor &PP = SemaR.getPreprocessor();
7703 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7704 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7705 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7706 // After we have saved the token reset the current one to something which
7707 // is safe (semi colon usually means empty decl)
7708 Token& Tok = const_cast<Token&>(P.getCurToken());
7709 Tok.setKind(tok::semi);
7710
7711 // We can't PushDeclContext, because we go up and the routine that pops
7712 // the DeclContext assumes that we drill down always.
7713 // We have to be on the global context. At that point we are in a
7714 // wrapper function so the parent context must be the global.
7715 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7716 SemaR.TUScope);
7717
7718 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7719 if (specObj) {
7720 if (!LookupCtx) {
7721 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7722 } else {
7723 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7724 }
7725 }
7726 return specObj;
7727}
7728
7729////////////////////////////////////////////////////////////////////////////////
7730/// Inject function as a friend into klass.
7731/// With function being f in void f() {new N::PrivKlass(); } this enables
7732/// I/O of non-public classes.
7733
7734void TCling::AddFriendToClass(clang::FunctionDecl* function,
7735 clang::CXXRecordDecl* klass) const
7736{
7737 using namespace clang;
7738 ASTContext& Ctx = klass->getASTContext();
7739 FriendDecl::FriendUnion friendUnion(function);
7740 // one dummy object for the source location
7741 SourceLocation sl;
7742 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7743 klass->pushFriendDecl(friendDecl);
7744}
7745
7746//______________________________________________________________________________
7747//
7748// DeclId getter.
7749//
7750
7751////////////////////////////////////////////////////////////////////////////////
7752/// Return a unique identifier of the declaration represented by the
7753/// CallFunc
7754
7756{
7757 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7758 return 0;
7759}
7760
7761////////////////////////////////////////////////////////////////////////////////
7762/// Return a (almost) unique identifier of the declaration represented by the
7763/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7764/// when the underlying class is a template instance involving one of the
7765/// opaque typedef.
7766
7768{
7769 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7770 return 0;
7771}
7772
7773////////////////////////////////////////////////////////////////////////////////
7774/// Return a unique identifier of the declaration represented by the
7775/// MethodInfo
7776
7777TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7778{
7779 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7780 return 0;
7781}
7782
7783////////////////////////////////////////////////////////////////////////////////
7784/// Return a unique identifier of the declaration represented by the
7785/// MethodInfo
7786
7788{
7789 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7790 return 0;
7791}
7792
7793////////////////////////////////////////////////////////////////////////////////
7794/// Return a unique identifier of the declaration represented by the
7795/// TypedefInfo
7796
7798{
7799 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7800 return 0;
7801}
7802
7803//______________________________________________________________________________
7804//
7805// CallFunc interface
7806//
7807
7808////////////////////////////////////////////////////////////////////////////////
7809
7810void TCling::CallFunc_Delete(CallFunc_t* func) const
7811{
7812 delete (TClingCallFunc*) func;
7813}
7814
7815////////////////////////////////////////////////////////////////////////////////
7816
7817void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7818{
7819 TClingCallFunc* f = (TClingCallFunc*) func;
7820 f->Exec(address);
7821}
7822
7823////////////////////////////////////////////////////////////////////////////////
7824
7825void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7826{
7827 TClingCallFunc* f = (TClingCallFunc*) func;
7828 f->Exec(address, &val);
7829}
7830
7831////////////////////////////////////////////////////////////////////////////////
7832
7833void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7834{
7835 TClingCallFunc* f = (TClingCallFunc*) func;
7836 f->ExecWithReturn(address, ret);
7837}
7838
7839////////////////////////////////////////////////////////////////////////////////
7840
7841void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7842 const void* args[] /*=0*/,
7843 int nargs /*=0*/,
7844 void* ret/*=0*/) const
7845{
7846 TClingCallFunc* f = (TClingCallFunc*) func;
7847 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7848}
7849
7850////////////////////////////////////////////////////////////////////////////////
7851
7852Long_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7853{
7854 TClingCallFunc* f = (TClingCallFunc*) func;
7855 return f->ExecInt(address);
7856}
7857
7858////////////////////////////////////////////////////////////////////////////////
7859
7860Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7861{
7862 TClingCallFunc* f = (TClingCallFunc*) func;
7863 return f->ExecInt64(address);
7864}
7865
7866////////////////////////////////////////////////////////////////////////////////
7867
7868Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7869{
7870 TClingCallFunc* f = (TClingCallFunc*) func;
7871 return f->ExecDouble(address);
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876CallFunc_t* TCling::CallFunc_Factory() const
7877{
7879 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl(), *fNormalizedCtxt);
7880}
7881
7882////////////////////////////////////////////////////////////////////////////////
7883
7884CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7885{
7886 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7887}
7888
7889////////////////////////////////////////////////////////////////////////////////
7890
7891MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7892{
7893 TClingCallFunc* f = (TClingCallFunc*) func;
7894 return (MethodInfo_t*) f->FactoryMethod();
7895}
7896
7897////////////////////////////////////////////////////////////////////////////////
7898
7899void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7900{
7901 TClingCallFunc* f = (TClingCallFunc*) func;
7902 f->IgnoreExtraArgs(ignore);
7903}
7904
7905////////////////////////////////////////////////////////////////////////////////
7906
7907void TCling::CallFunc_Init(CallFunc_t* func) const
7908{
7910 TClingCallFunc* f = (TClingCallFunc*) func;
7911 f->Init();
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915
7916bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7917{
7918 TClingCallFunc* f = (TClingCallFunc*) func;
7919 return f->IsValid();
7920}
7921
7922////////////////////////////////////////////////////////////////////////////////
7923
7925TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7926{
7927 TClingCallFunc* f = (TClingCallFunc*) func;
7928 return f->IFacePtr();
7929}
7930
7931////////////////////////////////////////////////////////////////////////////////
7932
7933void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7934{
7935 TClingCallFunc* f = (TClingCallFunc*) func;
7936 f->ResetArg();
7937}
7938
7939////////////////////////////////////////////////////////////////////////////////
7940
7941void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7942{
7943 TClingCallFunc* f = (TClingCallFunc*) func;
7944 f->SetArg(param);
7945}
7946
7947////////////////////////////////////////////////////////////////////////////////
7948
7949void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7950{
7951 TClingCallFunc* f = (TClingCallFunc*) func;
7952 f->SetArg(param);
7953}
7954
7955////////////////////////////////////////////////////////////////////////////////
7956
7957void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7958{
7959 TClingCallFunc* f = (TClingCallFunc*) func;
7960 f->SetArg(param);
7961}
7962
7963////////////////////////////////////////////////////////////////////////////////
7964
7965void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7966{
7967 TClingCallFunc* f = (TClingCallFunc*) func;
7968 f->SetArg(param);
7969}
7970
7971////////////////////////////////////////////////////////////////////////////////
7972
7973void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7974{
7975 TClingCallFunc* f = (TClingCallFunc*) func;
7976 f->SetArg(param);
7977}
7978
7979////////////////////////////////////////////////////////////////////////////////
7980
7981void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7982{
7983 TClingCallFunc* f = (TClingCallFunc*) func;
7984 f->SetArg(param);
7985}
7986
7987////////////////////////////////////////////////////////////////////////////////
7988
7989void TCling::CallFunc_SetArgArray(CallFunc_t* func, Long_t* paramArr, Int_t nparam) const
7990{
7991 TClingCallFunc* f = (TClingCallFunc*) func;
7992 f->SetArgArray(paramArr, nparam);
7993}
7994
7995////////////////////////////////////////////////////////////////////////////////
7996
7997void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7998{
7999 TClingCallFunc* f = (TClingCallFunc*) func;
8000 f->SetArgs(param);
8001}
8002
8003////////////////////////////////////////////////////////////////////////////////
8004
8005void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Long_t* offset) const
8006{
8007 TClingCallFunc* f = (TClingCallFunc*) func;
8008 TClingClassInfo* ci = (TClingClassInfo*) info;
8009 f->SetFunc(ci, method, params, offset);
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013
8014void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Long_t* offset) const
8015{
8016 TClingCallFunc* f = (TClingCallFunc*) func;
8017 TClingClassInfo* ci = (TClingClassInfo*) info;
8018 f->SetFunc(ci, method, params, objectIsConst, offset);
8019}
8020////////////////////////////////////////////////////////////////////////////////
8021
8022void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8023{
8024 TClingCallFunc* f = (TClingCallFunc*) func;
8025 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8026 f->SetFunc(minfo);
8027}
8028
8029////////////////////////////////////////////////////////////////////////////////
8030/// Interface to cling function
8031
8032void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8033{
8034 TClingCallFunc* f = (TClingCallFunc*) func;
8035 TClingClassInfo* ci = (TClingClassInfo*) info;
8036 f->SetFuncProto(ci, method, proto, offset, mode);
8037}
8038
8039////////////////////////////////////////////////////////////////////////////////
8040/// Interface to cling function
8041
8042void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8043{
8044 TClingCallFunc* f = (TClingCallFunc*) func;
8045 TClingClassInfo* ci = (TClingClassInfo*) info;
8046 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8047}
8048
8049////////////////////////////////////////////////////////////////////////////////
8050/// Interface to cling function
8051
8052void 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
8053{
8054 TClingCallFunc* f = (TClingCallFunc*) func;
8055 TClingClassInfo* ci = (TClingClassInfo*) info;
8056 llvm::SmallVector<clang::QualType, 4> funcProto;
8057 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8058 iter != end; ++iter) {
8059 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8060 }
8061 f->SetFuncProto(ci, method, funcProto, offset, mode);
8062}
8063
8064////////////////////////////////////////////////////////////////////////////////
8065/// Interface to cling function
8066
8067void 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
8068{
8069 TClingCallFunc* f = (TClingCallFunc*) func;
8070 TClingClassInfo* ci = (TClingClassInfo*) info;
8071 llvm::SmallVector<clang::QualType, 4> funcProto;
8072 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8073 iter != end; ++iter) {
8074 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8075 }
8076 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8077}
8078
8079std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8080{
8081 TClingCallFunc *f = (TClingCallFunc *)func;
8082 std::string wrapper_name;
8083 std::string wrapper;
8084 f->get_wrapper_code(wrapper_name, wrapper);
8085 return wrapper;
8086}
8087
8088//______________________________________________________________________________
8089//
8090// ClassInfo interface
8091//
8092
8093////////////////////////////////////////////////////////////////////////////////
8094/// Return true if the entity pointed to by 'declid' is declared in
8095/// the context described by 'info'. If info is null, look into the
8096/// global scope (translation unit scope).
8097
8098Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8099{
8100 if (!declid)
8101 return kFALSE;
8102
8103 const clang::DeclContext *ctxt = nullptr;
8104 if (info) {
8105 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8106 } else {
8107 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8108 }
8109 if (!ctxt)
8110 return kFALSE;
8111
8112 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8113 if (!decl)
8114 return kFALSE;
8115
8116 const clang::DeclContext *declDC = decl->getDeclContext();
8117 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8118 while (true) {
8119 if (declDC->isTransparentContext()) {
8120 declDC = declDC->getParent();
8121 continue;
8122 }
8123 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8124 if (declRD->isAnonymousStructOrUnion()) {
8125 declDC = declRD->getParent();
8126 continue;
8127 }
8128 }
8129 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8130 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8131 declDC = declNS->getParent();
8132 continue;
8133 }
8134 }
8135 break;
8136 }
8137
8138 return declDC->Equals(ctxt);
8139}
8140
8141////////////////////////////////////////////////////////////////////////////////
8142
8144{
8145 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8146 return TClinginfo->ClassProperty();
8147}
8148
8149////////////////////////////////////////////////////////////////////////////////
8150
8151void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8152{
8153 delete (TClingClassInfo*) cinfo;
8154}
8155
8156////////////////////////////////////////////////////////////////////////////////
8157
8158void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8159{
8160 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8161 TClinginfo->Delete(arena,*fNormalizedCtxt);
8162}
8163
8164////////////////////////////////////////////////////////////////////////////////
8165
8166void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8167{
8168 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8169 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8170}
8171
8172////////////////////////////////////////////////////////////////////////////////
8173
8174void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8175{
8176 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8177 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8178}
8179
8180////////////////////////////////////////////////////////////////////////////////
8181
8182ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8183{
8185 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8186}
8187
8188////////////////////////////////////////////////////////////////////////////////
8189
8190ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8191{
8192 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8193}
8194
8195////////////////////////////////////////////////////////////////////////////////
8196
8197ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8198{
8200 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8201}
8202
8203ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8204{
8206 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8207}
8208
8209
8210////////////////////////////////////////////////////////////////////////////////
8211
8212int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8213{
8214 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8215 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8216}
8217
8218////////////////////////////////////////////////////////////////////////////////
8219
8220bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8221{
8222 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8224}
8225
8226////////////////////////////////////////////////////////////////////////////////
8227
8228bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8229{
8230 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8231 return TClinginfo->HasMethod(name);
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235
8236void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8237{
8239 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8240 TClinginfo->Init(name);
8241}
8242
8243////////////////////////////////////////////////////////////////////////////////
8244
8245void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8246{
8248 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8249 TClinginfo->Init(tagnum);
8250}
8251
8252////////////////////////////////////////////////////////////////////////////////
8253
8254bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8255{
8256 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8257 return TClinginfo->IsBase(name);
8258}
8259
8260////////////////////////////////////////////////////////////////////////////////
8261
8262bool TCling::ClassInfo_IsEnum(const char* name) const
8263{
8265}
8266
8267////////////////////////////////////////////////////////////////////////////////
8268
8270{
8271 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8272 return TClinginfo->IsScopedEnum();
8273}
8274
8275
8276////////////////////////////////////////////////////////////////////////////////
8277
8279{
8280 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8281 return TClinginfo->GetUnderlyingType();
8282}
8283
8284
8285////////////////////////////////////////////////////////////////////////////////
8286
8287bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8288{
8289 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8290 return TClinginfo->IsLoaded();
8291}
8292
8293////////////////////////////////////////////////////////////////////////////////
8294
8295bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8296{
8297 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8298 return TClinginfo->IsValid();
8299}
8300
8301////////////////////////////////////////////////////////////////////////////////
8302
8303bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8304{
8305 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8306 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8307}
8308
8309////////////////////////////////////////////////////////////////////////////////
8310
8311bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8312{
8313 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8314 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8315}
8316
8317////////////////////////////////////////////////////////////////////////////////
8318
8319int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8320{
8321 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8322 return TClinginfo->Next();
8323}
8324
8325////////////////////////////////////////////////////////////////////////////////
8326
8327void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8328{
8329 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8330 return TClinginfo->New(*fNormalizedCtxt);
8331}
8332
8333////////////////////////////////////////////////////////////////////////////////
8334
8335void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8336{
8337 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8338 return TClinginfo->New(n,*fNormalizedCtxt);
8339}
8340
8341////////////////////////////////////////////////////////////////////////////////
8342
8343void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8344{
8345 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8346 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8347}
8348
8349////////////////////////////////////////////////////////////////////////////////
8350
8351void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8352{
8353 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8354 return TClinginfo->New(arena,*fNormalizedCtxt);
8355}
8356
8357////////////////////////////////////////////////////////////////////////////////
8358
8359Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8360{
8361 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8362 return TClinginfo->Property();
8363}
8364
8365////////////////////////////////////////////////////////////////////////////////
8366
8367int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8368{
8369 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8370 return TClinginfo->Size();
8371}
8372
8373////////////////////////////////////////////////////////////////////////////////
8374
8375Long_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8376{
8377 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8378 return TClinginfo->Tagnum();
8379}
8380
8381////////////////////////////////////////////////////////////////////////////////
8382
8383const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8384{
8385 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8386 return TClinginfo->FileName();
8387}
8388
8389////////////////////////////////////////////////////////////////////////////////
8390
8391const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8392{
8393 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8394 TTHREAD_TLS_DECL(std::string,output);
8395 TClinginfo->FullName(output,*fNormalizedCtxt);
8396 return output.c_str();
8397}
8398
8399////////////////////////////////////////////////////////////////////////////////
8400
8401const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8402{
8403 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8404 return TClinginfo->Name();
8405}
8406
8407////////////////////////////////////////////////////////////////////////////////
8408
8409const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8410{
8411 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8412 return TClinginfo->Title();
8413}
8414
8415////////////////////////////////////////////////////////////////////////////////
8416
8417const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8418{
8419 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8420 return TClinginfo->TmpltName();
8421}
8422
8423
8424
8425//______________________________________________________________________________
8426//
8427// BaseClassInfo interface
8428//
8429
8430////////////////////////////////////////////////////////////////////////////////
8431
8432void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8433{
8434 delete(TClingBaseClassInfo*) bcinfo;
8435}
8436
8437////////////////////////////////////////////////////////////////////////////////
8438
8439BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8440{
8442 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8443 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8444}
8445
8446////////////////////////////////////////////////////////////////////////////////
8447
8448BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8449 ClassInfo_t* base) const
8450{
8452 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8453 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8454 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8455}
8456
8457////////////////////////////////////////////////////////////////////////////////
8458
8459int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8460{
8461 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8462 return TClinginfo->Next();
8463}
8464
8465////////////////////////////////////////////////////////////////////////////////
8466
8467int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8468{
8469 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8470 return TClinginfo->Next(onlyDirect);
8471}
8472
8473////////////////////////////////////////////////////////////////////////////////
8474
8475Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8476{
8477 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8478 return TClinginfo->Offset(address, isDerivedObject);
8479}
8480
8481////////////////////////////////////////////////////////////////////////////////
8482
8483Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8484{
8485 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8486 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8487 // Offset to the class itself.
8488 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8489 return 0;
8490 }
8491 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8492}
8493
8494////////////////////////////////////////////////////////////////////////////////
8495
8496Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8497{
8498 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8499 return TClinginfo->Property();
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503
8504ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8505{
8506 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8507 return (ClassInfo_t *)TClinginfo->GetBase();
8508}
8509
8510////////////////////////////////////////////////////////////////////////////////
8511
8512Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8513{
8514 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8515 return TClinginfo->Tagnum();
8516}
8517
8518////////////////////////////////////////////////////////////////////////////////
8519
8520const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8521{
8522 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8523 TTHREAD_TLS_DECL(std::string,output);
8524 TClinginfo->FullName(output,*fNormalizedCtxt);
8525 return output.c_str();
8526}
8527
8528////////////////////////////////////////////////////////////////////////////////
8529
8530const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8531{
8532 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8533 return TClinginfo->Name();
8534}
8535
8536////////////////////////////////////////////////////////////////////////////////
8537
8538const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8539{
8540 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8541 return TClinginfo->TmpltName();
8542}
8543
8544//______________________________________________________________________________
8545//
8546// DataMemberInfo interface
8547//
8548
8549////////////////////////////////////////////////////////////////////////////////
8550
8551int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8552{
8553 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8554 return TClinginfo->ArrayDim();
8555}
8556
8557////////////////////////////////////////////////////////////////////////////////
8558
8559void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8560{
8561 delete(TClingDataMemberInfo*) dminfo;
8562}
8563
8564////////////////////////////////////////////////////////////////////////////////
8565
8566DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8567{
8569 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8570 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8571}
8572
8573////////////////////////////////////////////////////////////////////////////////
8574
8575DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8576{
8578 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8579 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8580 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8581}
8582
8583////////////////////////////////////////////////////////////////////////////////
8584
8585DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8586{
8587 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8588 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8589}
8590
8591////////////////////////////////////////////////////////////////////////////////
8592
8593bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8594{
8595 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8596 return TClinginfo->IsValid();
8597}
8598
8599////////////////////////////////////////////////////////////////////////////////
8600
8601int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8602{
8603 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8604 return TClinginfo->MaxIndex(dim);
8605}
8606
8607////////////////////////////////////////////////////////////////////////////////
8608
8609int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8610{
8611 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8612 return TClinginfo->Next();
8613}
8614
8615////////////////////////////////////////////////////////////////////////////////
8616
8617Long_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8618{
8619 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8620 return TClinginfo->Offset();
8621}
8622
8623////////////////////////////////////////////////////////////////////////////////
8624
8625Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8626{
8627 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8628 return TClinginfo->Property();
8629}
8630
8631////////////////////////////////////////////////////////////////////////////////
8632
8633Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8634{
8635 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8636 return TClinginfo->TypeProperty();
8637}
8638
8639////////////////////////////////////////////////////////////////////////////////
8640
8641int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8642{
8643 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8644 return TClinginfo->TypeSize();
8645}
8646
8647////////////////////////////////////////////////////////////////////////////////
8648
8649const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8650{
8651 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8652 return TClinginfo->TypeName();
8653}
8654
8655////////////////////////////////////////////////////////////////////////////////
8656
8657const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8658{
8659 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8660 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8661}
8662
8663////////////////////////////////////////////////////////////////////////////////
8664
8665const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8666{
8667 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8668 return TClinginfo->Name();
8669}
8670
8671////////////////////////////////////////////////////////////////////////////////
8672
8673const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8674{
8675 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8676 return TClinginfo->Title();
8677}
8678
8679////////////////////////////////////////////////////////////////////////////////
8680
8681const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8682{
8683 TTHREAD_TLS_DECL(std::string,result);
8684
8685 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8686 result = TClinginfo->ValidArrayIndex().str();
8687 return result.c_str();
8688}
8689
8690////////////////////////////////////////////////////////////////////////////////
8691
8692void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8693{
8694 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8695 ASTContext &C = decl->getASTContext();
8696 SourceRange commentRange; // this is a fake comment range
8697 decl->addAttr( new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8698}
8699
8700//______________________________________________________________________________
8701//
8702// Function Template interface
8703//
8704
8705////////////////////////////////////////////////////////////////////////////////
8706
8707static void ConstructorName(std::string &name, const clang::Decl *decl,
8708 cling::Interpreter &interp,
8709 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8710{
8711 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8712 if (!td) return;
8713
8714 clang::QualType qualType(td->getTypeForDecl(),0);
8715 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8716 unsigned int level = 0;
8717 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8718 if (name[cursor] == '>') ++level;
8719 else if (name[cursor] == '<' && level) --level;
8720 else if (level == 0 && name[cursor] == ':') {
8721 name.erase(0,cursor+1);
8722 break;
8723 }
8724 }
8725}
8726
8727////////////////////////////////////////////////////////////////////////////////
8728
8729void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8730{
8731 output.clear();
8732
8733 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8734 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8735 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8736 }
8737 if (!FD) {
8738 Error("GetFunctionName", "NULL Decl!");
8739 return;
8740 }
8741
8742 // For using-decls, show "Derived", not "Base", i.e. use the
8743 // name of the decl context of the UsingShadowDecl (aka `decl`)
8744 // not the name of FD's decl context.
8745 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8746 {
8748
8749 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8750 {
8752 output.insert(output.begin(), '~');
8753 } else {
8754 llvm::raw_string_ostream stream(output);
8755 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8756 // Don't trigger fopen of the source file to count lines:
8757 printPolicy.AnonymousTagLocations = false;
8758 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8759 }
8760}
8761
8762////////////////////////////////////////////////////////////////////////////////
8763/// Return a unique identifier of the declaration represented by the
8764/// FuncTempInfo
8765
8767{
8768 return (DeclId_t)info;
8769}
8770
8771////////////////////////////////////////////////////////////////////////////////
8772/// Delete the FuncTempInfo_t
8773
8774void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8775{
8776 // Currently the address of ft_info is actually the decl itself,
8777 // so we have nothing to do.
8778}
8779
8780////////////////////////////////////////////////////////////////////////////////
8781/// Construct a FuncTempInfo_t
8782
8783FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8784{
8785 // Currently the address of ft_info is actually the decl itself,
8786 // so we have nothing to do.
8787
8788 return (FuncTempInfo_t*)const_cast<void*>(declid);
8789}
8790
8791////////////////////////////////////////////////////////////////////////////////
8792/// Construct a FuncTempInfo_t
8793
8794FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8795{
8796 // Currently the address of ft_info is actually the decl itself,
8797 // so we have nothing to do.
8798
8799 return (FuncTempInfo_t*)ft_info;
8800}
8801
8802////////////////////////////////////////////////////////////////////////////////
8803/// Check validity of a FuncTempInfo_t
8804
8805Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8806{
8807 // Currently the address of ft_info is actually the decl itself,
8808 // so we have nothing to do.
8809
8810 return t_info != 0;
8811}
8812
8813////////////////////////////////////////////////////////////////////////////////
8814/// Return the maximum number of template arguments of the
8815/// function template described by ft_info.
8816
8817UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8818{
8819 if (!ft_info) return 0;
8820 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8821 return ft->getTemplateParameters()->size();
8822}
8823
8824////////////////////////////////////////////////////////////////////////////////
8825/// Return the number of required template arguments of the
8826/// function template described by ft_info.
8827
8829{
8830 if (!ft_info) return 0;
8831 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8832 return ft->getTemplateParameters()->getMinRequiredArguments();
8833}
8834
8835////////////////////////////////////////////////////////////////////////////////
8836/// Return the property of the function template.
8837
8838Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8839{
8840 if (!ft_info) return 0;
8841
8842 long property = 0L;
8843 property |= kIsCompiled;
8844
8845 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8846
8847 switch (ft->getAccess()) {
8848 case clang::AS_public:
8849 property |= kIsPublic;
8850 break;
8851 case clang::AS_protected:
8852 property |= kIsProtected;
8853 break;
8854 case clang::AS_private:
8855 property |= kIsPrivate;
8856 break;
8857 case clang::AS_none:
8858 if (ft->getDeclContext()->isNamespace())
8859 property |= kIsPublic;
8860 break;
8861 default:
8862 // IMPOSSIBLE
8863 break;
8864 }
8865
8866 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8867 if (const clang::CXXMethodDecl *md =
8868 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8869 if (md->getMethodQualifiers().hasConst()) {
8870 property |= kIsConstant | kIsConstMethod;
8871 }
8872 if (md->isVirtual()) {
8873 property |= kIsVirtual;
8874 }
8875 if (md->isPure()) {
8876 property |= kIsPureVirtual;
8877 }
8878 if (const clang::CXXConstructorDecl *cd =
8879 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8880 if (cd->isExplicit()) {
8881 property |= kIsExplicit;
8882 }
8883 }
8884 else if (const clang::CXXConversionDecl *cd =
8885 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8886 if (cd->isExplicit()) {
8887 property |= kIsExplicit;
8888 }
8889 }
8890 }
8891 return property;
8892}
8893
8894////////////////////////////////////////////////////////////////////////////////
8895/// Return the property not already defined in Property
8896/// See TDictionary's EFunctionProperty
8897
8898Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8899{
8900 if (!ft_info) return 0;
8901
8902 long property = 0L;
8903 property |= kIsCompiled;
8904
8905 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8906 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8907
8908 if (fd->isOverloadedOperator())
8909 property |= kIsOperator;
8910 if (llvm::isa<clang::CXXConversionDecl>(fd))
8911 property |= kIsConversion;
8912 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8913 property |= kIsConstructor;
8914 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8915 property |= kIsDestructor;
8916 if (fd->isInlined())
8917 property |= kIsInlined;
8918 return property;
8919}
8920
8921////////////////////////////////////////////////////////////////////////////////
8922/// Return the name of this function template.
8923
8924void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8925{
8926 output.Clear();
8927 if (!ft_info) return;
8928 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8929 std::string buf;
8930 GetFunctionName(ft->getTemplatedDecl(), buf);
8931 output = buf;
8932}
8933
8934////////////////////////////////////////////////////////////////////////////////
8935/// Return the comments associates with this function template.
8936
8937void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8938{
8939 output.Clear();
8940 if (!ft_info) return;
8941 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8942
8943 // Iterate over the redeclarations, we can have multiple definitions in the
8944 // redecl chain (came from merging of pcms).
8945 if (const RedeclarableTemplateDecl *AnnotFD
8946 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8947 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8948 output = A->getAnnotation().str();
8949 return;
8950 }
8951 }
8952 if (!ft->isFromASTFile()) {
8953 // Try to get the comment from the header file if present
8954 // but not for decls from AST file, where rootcling would have
8955 // created an annotation
8957 }
8958}
8959
8960
8961//______________________________________________________________________________
8962//
8963// MethodInfo interface
8964//
8965
8966////////////////////////////////////////////////////////////////////////////////
8967/// Interface to cling function
8968
8969void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8970{
8971 delete(TClingMethodInfo*) minfo;
8972}
8973
8974////////////////////////////////////////////////////////////////////////////////
8975
8976void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8977{
8978 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8979 info->CreateSignature(signature);
8980}
8981
8982////////////////////////////////////////////////////////////////////////////////
8983
8984MethodInfo_t* TCling::MethodInfo_Factory() const
8985{
8987 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8988}
8989
8990////////////////////////////////////////////////////////////////////////////////
8991
8992MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8993{
8995 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8996}
8997
8998////////////////////////////////////////////////////////////////////////////////
8999
9000MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9001{
9002 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9004 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9005}
9006
9007////////////////////////////////////////////////////////////////////////////////
9008
9009MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9010{
9011 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9012}
9013
9014////////////////////////////////////////////////////////////////////////////////
9015
9016void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9017{
9018 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9019 return info->InterfaceMethod(*fNormalizedCtxt);
9020}
9021
9022////////////////////////////////////////////////////////////////////////////////
9023
9024bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9025{
9026 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9027 return info->IsValid();
9028}
9029
9030////////////////////////////////////////////////////////////////////////////////
9031
9032int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9033{
9034 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9035 return info->NArg();
9036}
9037
9038////////////////////////////////////////////////////////////////////////////////
9039
9040int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9041{
9042 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9043 return info->NDefaultArg();
9044}
9045
9046////////////////////////////////////////////////////////////////////////////////
9047
9048int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9049{
9050 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9051 return info->Next();
9052}
9053
9054////////////////////////////////////////////////////////////////////////////////
9055
9056Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9057{
9058 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9059 return info->Property();
9060}
9061
9062////////////////////////////////////////////////////////////////////////////////
9063
9065{
9066 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9067 return info->ExtraProperty();
9068}
9069
9070////////////////////////////////////////////////////////////////////////////////
9071
9072TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9073{
9074 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9075 return (TypeInfo_t*)info->Type();
9076}
9077
9078////////////////////////////////////////////////////////////////////////////////
9079
9080const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9081{
9082 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9083 TTHREAD_TLS_DECL(TString, mangled_name);
9084 mangled_name = info->GetMangledName();
9085 return mangled_name;
9086}
9087
9088////////////////////////////////////////////////////////////////////////////////
9089
9090const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9091{
9092 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9093 return info->GetPrototype();
9094}
9095
9096////////////////////////////////////////////////////////////////////////////////
9097
9098const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9099{
9100 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9101 return info->Name();
9102}
9103
9104////////////////////////////////////////////////////////////////////////////////
9105
9106const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9107{
9108 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9109 return info->TypeName();
9110}
9111
9112////////////////////////////////////////////////////////////////////////////////
9113
9114std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9115{
9116 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9117 if (info && info->IsValid())
9118 return info->Type()->NormalizedName(*fNormalizedCtxt);
9119 else
9120 return "";
9121}
9122
9123////////////////////////////////////////////////////////////////////////////////
9124
9125const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9126{
9127 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9128 return info->Title();
9129}
9130
9131////////////////////////////////////////////////////////////////////////////////
9132
9134{
9135 if (func) {
9136 return MethodInfo_MethodCallReturnType(func->fInfo);
9137 } else {
9138 return EReturnType::kOther;
9139 }
9140}
9141
9142////////////////////////////////////////////////////////////////////////////////
9143
9145{
9146 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9147 if (info && info->IsValid()) {
9148 TClingTypeInfo *typeinfo = info->Type();
9149 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9150 if (QT->isEnumeralType()) {
9151 return EReturnType::kLong;
9152 } else if (QT->isPointerType()) {
9153 // Look for char*
9154 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9155 if ( QT->isCharType() ) {
9156 return EReturnType::kString;
9157 } else {
9158 return EReturnType::kOther;
9159 }
9160 } else if ( QT->isFloatingType() ) {
9161 int sz = typeinfo->Size();
9162 if (sz == 4 || sz == 8) {
9163 // Support only float and double.
9164 return EReturnType::kDouble;
9165 } else {
9166 return EReturnType::kOther;
9167 }
9168 } else if ( QT->isIntegerType() ) {
9169 int sz = typeinfo->Size();
9170 if (sz <= 8) {
9171 // Support only up to long long ... but
9172 // FIXME the TMethodCall::Execute only
9173 // return long (4 bytes) ...
9174 // The v5 implementation of TMethodCall::ReturnType
9175 // was not making the distinction so we let it go
9176 // as is for now, but we really need to upgrade
9177 // TMethodCall::Execute ...
9178 return EReturnType::kLong;
9179 } else {
9180 return EReturnType::kOther;
9181 }
9182 } else {
9183 return EReturnType::kOther;
9184 }
9185 } else {
9186 return EReturnType::kOther;
9187 }
9188}
9189
9190//______________________________________________________________________________
9191//
9192// MethodArgInfo interface
9193//
9194
9195////////////////////////////////////////////////////////////////////////////////
9196
9197void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9198{
9199 delete(TClingMethodArgInfo*) marginfo;
9200}
9201
9202////////////////////////////////////////////////////////////////////////////////
9203
9204MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9205{
9207 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9208}
9209
9210////////////////////////////////////////////////////////////////////////////////
9211
9212MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9213{
9215 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219
9220MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9221{
9222 return (MethodArgInfo_t*)
9224}
9225
9226////////////////////////////////////////////////////////////////////////////////
9227
9228bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9229{
9230 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9231 return info->IsValid();
9232}
9233
9234////////////////////////////////////////////////////////////////////////////////
9235
9236int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9237{
9238 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9239 return info->Next();
9240}
9241
9242////////////////////////////////////////////////////////////////////////////////
9243
9244Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9245{
9246 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9247 return info->Property();
9248}
9249
9250////////////////////////////////////////////////////////////////////////////////
9251
9252const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9253{
9254 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9255 return info->DefaultValue();
9256}
9257
9258////////////////////////////////////////////////////////////////////////////////
9259
9260const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9261{
9262 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9263 return info->Name();
9264}
9265
9266////////////////////////////////////////////////////////////////////////////////
9267
9268const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9269{
9270 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9271 return info->TypeName();
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275
9276std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9277{
9278 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9279 return info->Type()->NormalizedName(*fNormalizedCtxt);
9280}
9281
9282//______________________________________________________________________________
9283//
9284// TypeInfo interface
9285//
9286
9287////////////////////////////////////////////////////////////////////////////////
9288
9289void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9290{
9291 delete (TClingTypeInfo*) tinfo;
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9296TypeInfo_t* TCling::TypeInfo_Factory() const
9297{
9299 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9300}
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9304TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9305{
9307 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9308}
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9312TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9313{
9314 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9315}
9316
9317////////////////////////////////////////////////////////////////////////////////
9318
9319void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9320{
9322 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9323 TClinginfo->Init(name);
9324}
9325
9326////////////////////////////////////////////////////////////////////////////////
9327
9328bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9329{
9330 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9331 return TClinginfo->IsValid();
9332}
9333
9334////////////////////////////////////////////////////////////////////////////////
9335
9336const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9337{
9338 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9339 return TClinginfo->Name();
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343
9344Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9345{
9346 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9347 return TClinginfo->Property();
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351
9352int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9353{
9354 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9355 return TClinginfo->RefType();
9356}
9357
9358////////////////////////////////////////////////////////////////////////////////
9359
9360int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9361{
9362 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9363 return TClinginfo->Size();
9364}
9365
9366////////////////////////////////////////////////////////////////////////////////
9367
9368const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9369{
9370 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9371 return TClinginfo->TrueName(*fNormalizedCtxt);
9372}
9373
9374
9375//______________________________________________________________________________
9376//
9377// TypedefInfo interface
9378//
9379
9380////////////////////////////////////////////////////////////////////////////////
9381
9382void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9383{
9384 delete(TClingTypedefInfo*) tinfo;
9385}
9386
9387////////////////////////////////////////////////////////////////////////////////
9388
9389TypedefInfo_t* TCling::TypedefInfo_Factory() const
9390{
9392 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9393}
9394
9395////////////////////////////////////////////////////////////////////////////////
9396
9397TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9398{
9400 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9401}
9402
9403////////////////////////////////////////////////////////////////////////////////
9404
9405TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9406{
9407 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9408}
9409
9410////////////////////////////////////////////////////////////////////////////////
9411
9412void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9413 const char* name) const
9414{
9416 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9417 TClinginfo->Init(name);
9418}
9419
9420////////////////////////////////////////////////////////////////////////////////
9421
9422bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9423{
9424 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9425 return TClinginfo->IsValid();
9426}
9427
9428////////////////////////////////////////////////////////////////////////////////
9429
9430Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9431{
9432 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9433 return TClinginfo->Next();
9434}
9435
9436////////////////////////////////////////////////////////////////////////////////
9437
9438Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9439{
9440 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9441 return TClinginfo->Property();
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445
9446int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9447{
9448 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9449 return TClinginfo->Size();
9450}
9451
9452////////////////////////////////////////////////////////////////////////////////
9453
9454const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9455{
9456 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9457 return TClinginfo->TrueName(*fNormalizedCtxt);
9458}
9459
9460////////////////////////////////////////////////////////////////////////////////
9461
9462const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9463{
9464 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9465 return TClinginfo->Name();
9466}
9467
9468////////////////////////////////////////////////////////////////////////////////
9469
9470const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9471{
9472 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9473 return TClinginfo->Title();
9474}
9475
9476////////////////////////////////////////////////////////////////////////////////
9477
9479{
9480 if (!fInitialMutex) {
9482 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9483 }
9485 }
9486 // We will "forget" this lock once we backed out of all interpreter frames.
9487 // Here we are entering one, so ++.
9489}
9490
9491////////////////////////////////////////////////////////////////////////////////
9492
9494{
9495 if (!fInitialMutex)
9496 return;
9497 if (fInitialMutex.fRecurseCount == 0) {
9498 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9499 }
9500 else if (--fInitialMutex.fRecurseCount == 0) {
9501 // We have returned from all interpreter frames. Reset the initial lock state.
9502 fInitialMutex.fState.reset();
9503 }
9504}
9505
9506////////////////////////////////////////////////////////////////////////////////
9507/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9508
9510{
9511 if (gInterpreterMutex) {
9512 if (delta) {
9513 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9514 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9515 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9516 // Now that we have the lock, update the global
9517 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9518 std::swap(fInitialMutex, typedDelta->fInitialState);
9519 } else {
9520 // This case happens when EnableThreadSafety is first called from
9521 // the interpreter function we just handled.
9522 // Since thread safety was not enabled at the time we rewound, there was
9523 // no lock taken and even-though we should be locking the rest of this
9524 // interpreter handling/modifying code (since there might be threads in
9525 // flight), we can't because there would not be any lock guard to release the
9526 // locks
9528 Error("ApplyToInterpreterMutex",
9529 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9530 "so the rest of this function/stack execution might have race condition (with the other thread that thinks it has exclusive access to the interpreter state.");
9531 }
9532 }
9533}
9534
9535////////////////////////////////////////////////////////////////////////////////
9536/// Reset the interpreter lock to the state it had before interpreter-related
9537/// calls happened.
9538
9540{
9541 if (fInitialMutex) {
9542 // Need to start a new recurse count.
9543 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9544 std::swap(uniqueP->fInitialState, fInitialMutex);
9545 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9546 return uniqueP.release();
9547 }
9549 return nullptr;
9550}
#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 a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
const Ssiz_t kNPOS
Definition RtypesCore.h:115
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:92
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:73
unsigned long long ULong64_t
Definition RtypesCore.h:74
const Bool_t kTRUE
Definition RtypesCore.h:91
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:95
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:331
void * llvmLazyFunctionCreator(const std::string &mangled_name)
Autoload a library provided the mangled name of a missing symbol.
Definition TCling.cxx:687
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:569
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1328
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7224
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:6978
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:564
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:899
R__EXTERN int optind
Definition TCling.cxx:315
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:358
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:559
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:547
R__DLLEXPORT clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:213
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3826
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:341
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1941
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3083
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition TCling.cxx:3868
R__DLLEXPORT void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:234
R__DLLEXPORT void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:231
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1088
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:908
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:1073
R__DLLEXPORT clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:216
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:369
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:623
R__DLLEXPORT clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:219
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1667
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:618
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:697
R__DLLEXPORT bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:249
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1087
R__DLLEXPORT void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:606
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:583
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:554
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:594
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3844
R__DLLEXPORT TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:598
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:578
R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:222
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:379
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:634
#define R__DLLEXPORT
Definition TCling.cxx:150
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:350
static void * LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name, const cling::DynamicLibraryManager &DLM)
Definition TCling.cxx:6476
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:613
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1037
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1191
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8707
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:324
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:2422
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:7135
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:670
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1966
const char * fantomline
Definition TCling.cxx:846
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:573
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6220
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5404
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:590
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:1060
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:629
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7245
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:641
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
#define gDirectory
Definition TDirectory.h:290
@ kEnvUser
Definition TEnv.h:72
@ kEnvGlobal
Definition TEnv.h:71
@ kEnvLocal
Definition TEnv.h:73
#define R__ASSERT(e)
Definition TError.h:120
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:220
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
const Int_t kWarning
Definition TError.h:47
R__EXTERN Int_t gErrorIgnoreLevel
Definition TError.h:129
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:231
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:245
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:590
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
typedef void((*Func_t)())
@ kReadPermission
Definition TSystem.h:47
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:118
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
R__EXTERN TVirtualMutex * gGlobalMutex
#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()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:80
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3416
EState GetState() const
Definition TClass.h:485
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2875
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:511
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3775
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:4892
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:536
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2194
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3375
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5936
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5726
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5681
@ 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:5889
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:6063
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2886
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4192
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1809
@ 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:3440
@ 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:2957
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void ExecWithReturn(void *address, void *ret=nullptr)
long ExecInt(void *address)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
bool IsValid() const
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void SetArgArray(long *argArr, int narg)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
void IgnoreExtraArgs(bool ignore)
long long ExecInt64(void *address)
void SetArg(long arg)
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
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
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
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
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1013
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1021
std::string fContent
Definition TCling.h:607
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
virtual const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9252
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6092
virtual std::string CallFunc_GetWrapperCode(CallFunc_t *func) const
Definition TCling.cxx:8079
virtual void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const
Return the name of this function template.
Definition TCling.cxx:8924
virtual void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const
Return the comments associates with this function template.
Definition TCling.cxx:8937
virtual int TypedefInfo_Next(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9430
virtual bool DiagnoseIfInterpreterException(const std::exception &e) const
Definition TCling.cxx:2441
virtual bool ClassInfo_IsValid(ClassInfo_t *info) const
Definition TCling.cxx:8295
virtual bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const
Definition TCling.cxx:8269
Long_t Calc(const char *line, EErrorCode *error=0)
Directly execute an executable statement (e.g.
Definition TCling.cxx:3506
Bool_t HasPCMForLibrary(const char *libname) const
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3101
virtual MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const
Definition TCling.cxx:9009
virtual const char * TypeInfo_Name(TypeInfo_t *) const
Definition TCling.cxx:9336
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:4913
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6456
void ForgetMutexState()
Definition TCling.cxx:9493
virtual bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const
Definition TCling.cxx:8228
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:139
virtual MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const
Definition TCling.cxx:7891
virtual bool MethodInfo_IsValid(MethodInfo_t *minfo) const
Definition TCling.cxx:9024
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:119
Bool_t fLockProcessLine
Definition TCling.h:128
virtual const char * DataMemberInfo_TypeTrueName(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8657
void CreateListOfDataMembers(TClass *cl) const
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4378
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:2392
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:486
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:6873
virtual const char * MethodInfo_TypeName(MethodInfo_t *minfo) const
Definition TCling.cxx:9106
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const
Definition TCling.cxx:1903
virtual Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9438
virtual void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9197
virtual void LoadFunctionTemplates(TClass *cl) const
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4331
virtual CallFunc_t * CallFunc_Factory() const
Definition TCling.cxx:7876
virtual TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9405
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:150
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6747
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:7515
virtual Long_t ClassInfo_Tagnum(ClassInfo_t *info) const
Definition TCling.cxx:8375
void UpdateListOfTypes()
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3820
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false)
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7261
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4834
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8551
virtual bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const
Definition TCling.cxx:8254
virtual int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8459
virtual void GenericError(const char *error) const
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7428
virtual std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9276
virtual const char * ClassInfo_TmpltName(ClassInfo_t *info) const
Definition TCling.cxx:8417
virtual TEnum * CreateEnum(void *VD, TClass *cl) const
Definition TCling.cxx:459
virtual EReturnType MethodCallReturnType(TFunction *func) const
Definition TCling.cxx:9133
virtual int UnloadFile(const char *path) const
Definition TCling.cxx:7617
virtual int Evaluate(const char *, TInterpreterValue &)
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7645
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7681
virtual Long_t TypeInfo_Property(TypeInfo_t *tinfo) const
Definition TCling.cxx:9344
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:5039
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7523
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6858
void EndOfLineAction()
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3075
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:5017
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3291
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:2012
virtual const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8681
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:5543
void CreateListOfMethodArgs(TFunction *m) const
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4412
virtual void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const
Definition TCling.cxx:9412
virtual Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const
Definition TCling.cxx:9064
virtual void ReportDiagnosticsToErrorHandler(bool enable=true)
Report diagnostics to the ROOT error handler (see TError.h).
Definition TCling.cxx:7584
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1814
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1621
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7734
Bool_t fCxxModulesEnabled
Definition TCling.h:129
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6620
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition TCling.cxx:5269
virtual void FuncTempInfo_Delete(FuncTempInfo_t *) const
Delete the FuncTempInfo_t.
Definition TCling.cxx:8774
Bool_t SetSuspendAutoParsing(Bool_t value)
Suspend the Autoparsing of headers.
Definition TCling.cxx:7565
virtual DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8585
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const
Definition TCling.cxx:7925
virtual void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const
Definition TCling.cxx:7833
virtual MethodArgInfo_t * MethodArgInfo_Factory() const
Definition TCling.cxx:9204
virtual void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8559
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9509
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6517
virtual int LoadFile(const char *path) const
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7471
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &)
The call to Cling's tab complition.
Definition TCling.cxx:7637
virtual Long_t FuncTempInfo_Property(FuncTempInfo_t *) const
Return the property of the function template.
Definition TCling.cxx:8838
virtual TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const
Definition TCling.cxx:9072
virtual const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9268
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3586
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const
Definition TCling.cxx:8220
virtual bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8593
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:5420
Bool_t IsLoaded(const char *filename) const
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3126
const char * GetSharedLibs()
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6971
virtual const char * GetTopLevelMacroName() const
Return the file name of the current un-included interpreted file.
Definition TCling.cxx:5300
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:154
virtual DeclId_t GetDataMemberWithValue(const void *ptrvalue) const
NOT IMPLEMENTED.
Definition TCling.cxx:4825
virtual bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9228
Int_t ReloadAllSharedLibraryMaps()
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5825
virtual void SetErrmsgcallback(void *p) const
Set a callback to receive error messages.
Definition TCling.cxx:7575
virtual std::string ToString(const char *type, void *obj)
Definition TCling.cxx:1030
virtual const char * MethodInfo_Title(MethodInfo_t *minfo) const
Definition TCling.cxx:9125
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const
Definition TCling.cxx:8483
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8641
virtual ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const
Definition TCling.cxx:8182
virtual const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const
Definition TCling.cxx:9080
virtual bool CallFunc_IsValid(CallFunc_t *func) const
Definition TCling.cxx:7916
virtual const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8538
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:7505
virtual void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const
Definition TCling.cxx:8976
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx)
Definition TCling.cxx:9478
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:8098
std::set< size_t > fPayloads
Definition TCling.h:123
virtual const char * ClassInfo_Name(ClassInfo_t *info) const
Definition TCling.cxx:8401
Int_t UnloadLibraryMap(const char *library)
Unload library map entries coming from the specified library.
Definition TCling.cxx:5904
virtual ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const
Definition TCling.cxx:8504
TObjArray * fRootmapFiles
Definition TCling.h:127
virtual void CallFunc_Delete(CallFunc_t *func) const
Definition TCling.cxx:7810
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const
Definition TCling.cxx:8143
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:634
virtual bool ClassInfo_IsLoaded(ClassInfo_t *info) const
Definition TCling.cxx:8287
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:147
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:8212
Int_t DeleteGlobal(void *obj)
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3704
virtual const char * GetCurrentMacroName() const
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5347
virtual void TypeInfo_Delete(TypeInfo_t *tinfo) const
Definition TCling.cxx:9289
virtual Bool_t LoadText(const char *text) const
Load the declarations from text into the interpreter.
Definition TCling.cxx:7484
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:5084
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9539
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const
Definition TCling.cxx:8475
virtual int GetSecurityError() const
Interface to cling function.
Definition TCling.cxx:7458
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:8828
void ResetGlobals()
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition TCling.cxx:3661
virtual const char * ClassInfo_Title(ClassInfo_t *info) const
Definition TCling.cxx:8409
virtual void AddAvailableIndentifiers(TSeqCollection &Idents)
Definition TCling.cxx:2357
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8496
virtual FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const
Construct a FuncTempInfo_t.
Definition TCling.cxx:8783
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:4891
virtual void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const
Definition TCling.cxx:8174
virtual const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8520
virtual bool ClassInfo_IsEnum(const char *name) const
Definition TCling.cxx:8262
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const
Definition TCling.cxx:8566
Long_t ProcessLine(const char *line, EErrorCode *error=0)
Definition TCling.cxx:2452
virtual void TypedefInfo_Delete(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9382
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:3569
Int_t fGlobalsListSerial
Definition TCling.h:115
void RewindDictionary()
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3690
TString fSharedLibs
Definition TCling.h:114
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:624
virtual const char * MapCppName(const char *) const
Interface to cling function.
Definition TCling.cxx:7492
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6727
virtual Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8898
void PrintIntro()
No-op; see TRint instead.
Definition TCling.cxx:2618
virtual CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const
Definition TCling.cxx:7884
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8665
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:3052
Int_t DeleteVariable(const char *name)
Undeclare obj called name.
Definition TCling.cxx:3719
virtual int ClassInfo_Next(ClassInfo_t *info) const
Definition TCling.cxx:8319
static void * fgSetOfSpecials
Definition TCling.h:105
void AddIncludePath(const char *path)
Add a directory to the list of directories in which the interpreter looks for include files.
Definition TCling.cxx:2632
virtual void CallFunc_SetArgArray(CallFunc_t *func, Long_t *paramArr, Int_t nparam) const
Definition TCling.cxx:7989
virtual const char * MethodInfo_Name(MethodInfo_t *minfo) const
Definition TCling.cxx:9098
void ClearFileBusy()
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3031
virtual const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9260
virtual Long_t ClassInfo_Property(ClassInfo_t *info) const
Definition TCling.cxx:8359
Int_t fMore
Definition TCling.h:109
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:135
virtual int MethodInfo_Next(MethodInfo_t *minfo) const
Definition TCling.cxx:9048
const char * TypeName(const char *typeDesc)
Return the absolute type of typeDesc.
Definition TCling.cxx:5362
bool fIsShuttingDown
Definition TCling.h:188
void SaveContext()
Save the current Cling state.
Definition TCling.cxx:3780
std::set< TClass * > & GetModTClasses()
Definition TCling.h:567
virtual bool TypeInfo_IsValid(TypeInfo_t *tinfo) const
Definition TCling.cxx:9328
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)
Load library containing the specified class.
Definition TCling.cxx:6153
TClingCallbacks * fClingCallbacks
Definition TCling.h:140
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:4873
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:2383
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8625
void UpdateListOfGlobalFunctions()
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3813
virtual const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const
Definition TCling.cxx:9090
TString fIncludePath
Definition TCling.h:116
virtual bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Long_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const
Definition TCling.cxx:8303
virtual void * ClassInfo_New(ClassInfo_t *info) const
Definition TCling.cxx:8327
virtual void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const
Definition TCling.cxx:9319
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:7328
virtual const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8673
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6933
virtual EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const
Definition TCling.cxx:8278
virtual void CallFunc_Init(CallFunc_t *func) const
Definition TCling.cxx:7907
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:8817
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:4846
virtual void SetTempLevel(int val) const
Create / close a scope for temporaries.
Definition TCling.cxx:7611
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:4656
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7654
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:175
virtual void LoadEnums(TListOfEnums &cl) const
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4284
virtual void CallFunc_SetArg(CallFunc_t *func, Long_t param) const
Definition TCling.cxx:7941
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:7450
virtual void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const
Definition TCling.cxx:9016
Int_t UnloadAllSharedLibraryMaps()
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5886
virtual void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const
Definition TCling.cxx:7899
std::vector< cling::Value > * fTemporaries
Definition TCling.h:134
virtual Long_t MethodInfo_Property(MethodInfo_t *minfo) const
Definition TCling.cxx:9056
virtual std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const
Definition TCling.cxx:7630
virtual Long_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8617
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6044
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6956
virtual TypedefInfo_t * TypedefInfo_Factory() const
Definition TCling.cxx:9389
void UpdateListOfGlobals()
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3806
void ClearStack()
Delete existing temporary values.
Definition TCling.cxx:3039
std::map< const cling::Transaction *, size_t > fTransactionHeadersMap
Definition TCling.h:121
virtual int SetClassAutoparsing(int)
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7554
Bool_t fHeaderParsingOnDemand
Definition TCling.h:182
virtual int SetClassAutoLoading(int) const
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7536
Int_t RescanLibraryMap()
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5813
virtual int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8609
void Reset()
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3629
Int_t Load(const char *filenam, Bool_t system=kFALSE)
Load a library file in cling's memory.
Definition TCling.cxx:3436
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient)
Visit all members over members, recursing over base classes.
Definition TCling.cxx:2647
std::hash< std::string > fStringHashFunction
Definition TCling.h:125
TEnv * fMapfile
Definition TCling.h:118
const char * GetIncludePath()
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7342
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:579
virtual void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const
Definition TCling.cxx:8166
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8729
Long_t ExecuteMacro(const char *filename, EErrorCode *error=0)
Execute a cling macro.
Definition TCling.cxx:5287
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:4716
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:4932
virtual void CallFunc_Exec(CallFunc_t *func, void *address) const
Definition TCling.cxx:7817
virtual int DisplayIncludePath(FILE *fout) const
Interface to cling function.
Definition TCling.cxx:7391
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3351
virtual void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const
Definition TCling.cxx:411
void SaveGlobalsContext()
Save the current Cling state of global objects.
Definition TCling.cxx:3793
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:126
void ProcessClassesToUpdate()
Definition TCling.cxx:1982
virtual Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9244
virtual const char * GetSTLIncludePath() const
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7373
TString fRootmapLoadPath
Definition TCling.h:117
Int_t LoadLibraryMap(const char *rootmapfile=0)
Load map between class and library.
Definition TCling.cxx:5629
virtual std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const
Definition TCling.cxx:9114
void Execute(const char *function, const char *params, int *error=0)
Execute a global function with arguments params.
Definition TCling.cxx:5117
virtual const char * ClassInfo_FullName(ClassInfo_t *info) const
Definition TCling.cxx:8391
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE)
Generate a TClass for the given class.
Definition TCling.cxx:4435
virtual int TypeInfo_Size(TypeInfo_t *tinfo) const
Definition TCling.cxx:9360
virtual int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9236
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:136
virtual const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9454
Bool_t fIsAutoParsingSuspended
Definition TCling.h:183
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:5998
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4756
Long_t ProcessLineAsynch(const char *line, EErrorCode *error=0)
Let cling process a command line asynch.
Definition TCling.cxx:3481
virtual std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4367
Int_t SetClassSharedLibs(const char *cls, const char *libs)
Register the AutoLoading information for a class.
Definition TCling.cxx:5966
virtual void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const
Definition TCling.cxx:8236
virtual TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const
Definition TCling.cxx:9312
Bool_t CheckClassTemplate(const char *name)
Return true if there is a class template by the given name ...
Definition TCling.cxx:4240
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1699
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6612
TObjArray * GetRootMapFiles() const
Definition TCling.h:225
char fPrompt[64]
Definition TCling.h:111
void * fPrevLoadedDynLibInfo
Definition TCling.h:138
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition TCling.cxx:4405
virtual void SetDeclAttr(DeclId_t, const char *)
Definition TCling.cxx:8692
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8633
virtual void ShutDown()
Definition TCling.cxx:1658
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8649
virtual void CallFunc_SetArgs(CallFunc_t *func, const char *param) const
Definition TCling.cxx:7997
virtual const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8530
virtual void MethodInfo_Delete(MethodInfo_t *minfo) const
Interface to cling function.
Definition TCling.cxx:8969
virtual const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const
Definition TCling.cxx:9368
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:124
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:4068
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6721
virtual void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8432
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:3675
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:131
Bool_t IsLibraryLoaded(const char *libname) const
Definition TCling.cxx:3092
virtual void Initialize()
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1639
virtual void * FindSym(const char *entry) const
Interface to cling function.
Definition TCling.cxx:7420
virtual Long_t CallFunc_ExecInt(CallFunc_t *func, void *address) const
Definition TCling.cxx:7852
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const
Definition TCling.cxx:8601
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE)
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:3939
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:3490
virtual int TypeInfo_RefType(TypeInfo_t *) const
Definition TCling.cxx:9352
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:635
void LoadMacro(const char *filename, EErrorCode *error=0)
Load a macro file in cling's memory.
Definition TCling.cxx:3473
std::set< size_t > fLookedUpClasses
Definition TCling.h:122
virtual void CallFunc_ResetArg(CallFunc_t *func) const
Definition TCling.cxx:7933
virtual Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const
Definition TCling.cxx:7860
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8512
void ResetAll()
Reset the Cling state to its initial state.
Definition TCling.cxx:3645
virtual void ClassInfo_Delete(ClassInfo_t *info) const
Definition TCling.cxx:8151
virtual Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const
Definition TCling.cxx:7868
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:6269
virtual const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9470
void CreateListOfBaseClasses(TClass *cl) const
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4260
void RecursiveRemove(TObject *obj)
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3604
virtual MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9220
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6831
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6663
virtual const char * ClassInfo_FileName(ClassInfo_t *info) const
Definition TCling.cxx:8383
virtual void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition TCling.cxx:7841
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:5061
virtual int MethodInfo_NArg(MethodInfo_t *minfo) const
Definition TCling.cxx:9032
virtual FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const
Construct a FuncTempInfo_t.
Definition TCling.cxx:8794
void * fAutoLoadCallBack
Definition TCling.h:148
virtual int TypedefInfo_Size(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9446
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:132
virtual const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9462
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:8032
virtual int DisplayClass(FILE *fout, const char *name, int base, int start) const
Definition TCling.cxx:7382
const char * GetClassSharedLibs(const char *cls)
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7074
Bool_t IsErrorMessagesEnabled() const
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7314
ULong64_t fTransactionCount
Definition TCling.h:149
virtual Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8805
virtual BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const
Definition TCling.cxx:8439
virtual bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9422
virtual MethodInfo_t * MethodInfo_Factory() const
Definition TCling.cxx:8984
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:6411
virtual EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const
Definition TCling.cxx:9144
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:4994
virtual TypeInfo_t * TypeInfo_Factory() const
Definition TCling.cxx:9296
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition TCling.h:120
virtual int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const
Definition TCling.cxx:9040
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:4608
virtual void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Long_t *Offset) const
Definition TCling.cxx:8005
void CreateListOfMethods(TClass *cl) const
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4387
void UpdateListOfMethods(TClass *cl) const
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4396
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1681
virtual int ClassInfo_Size(ClassInfo_t *info) const
Definition TCling.cxx:8367
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6736
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6963
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
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
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
Small helper to keep current directory context.
Definition TDirectory.h:52
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:166
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h: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 void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:547
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * Remove(TObject *obj)
Remove object from the list.
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.
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
virtual const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
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...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h: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:357
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:308
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.
void Add(TObject *obj)
Definition TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual void Clear(Option_t *option="")
Remove all objects from the array.
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
virtual TObject * Remove(TObject *obj)
Remove object from array.
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
virtual void Clear(Option_t *="")
Definition TObject.h:115
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:879
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:323
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:696
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:893
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:921
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:403
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:867
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetBinDir()
Get the binary directory in the installation. Static utility function.
Definition TROOT.cxx:2917
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:2959
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2723
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2880
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:2969
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2890
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition TROOT.cxx:2938
Sequenceable collection abstract base class.
Int_t LastIndex() const
virtual void Add(TObject *obj)
Describe Streamer information for one class version.
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2197
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:912
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2217
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
TString & Prepend(const char *cs)
Definition TString.h:661
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
TString & Append(const char *cs)
Definition TString.h:564
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:2331
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1272
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:844
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:835
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1661
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3956
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4237
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1069
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1534
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1853
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:1396
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1079
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:1294
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:852
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2493
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:933
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1791
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2030
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:438
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:2834
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:870
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1544
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1645
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:886
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1030
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:733
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2016
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
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
bool CanConvertEnvValueToBool(const std::string &value)
bool ConvertEnvValueToBool(const std::string &value)
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
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.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h: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'.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h: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.
@ kDropStlDefault
Definition TClassEdit.h:81
EComplexType GetComplexType(const char *)
Definition file.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
Long_t fMemVirtual
Definition TSystem.h:196
Long_t fMemResident
Definition TSystem.h:195
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
Result of splitting a function declaration into fReturnType fScopeName::fFunctionName<fFunctionTempla...
Definition TClassEdit.h:249
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
Definition TClassEdit.h:254
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.
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:158
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:163
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
static void output(int code)
Definition gifencode.c:226