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 __CLING__ \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 return interp.loadModule(ModuleName, /*Complain=*/true);
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Loads the C++ modules that we require to run any ROOT program. This is just
1058/// supposed to make a C++ module from a modulemap available to the interpreter.
1059static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1060{
1061 for (const auto &modName : modules)
1062 LoadModule(modName, interp);
1063}
1064
1065static bool IsFromRootCling() {
1066 // rootcling also uses TCling for generating the dictionary ROOT files.
1067 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1068 return foundSymbol;
1069}
1070
1071/// Checks if there is an ASTFile on disk for the given module \c M.
1072static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1073{
1074 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1075
1076 std::string ModuleFileName;
1077 if (!HSOpts.PrebuiltModulePaths.empty())
1078 // Load the module from *only* in the prebuilt module path.
1079 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1080 if (FullFileName)
1081 *FullFileName = ModuleFileName;
1082
1083 return !ModuleFileName.empty();
1084}
1085
1086static bool HaveFullGlobalModuleIndex = false;
1087static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1088{
1089 CompilerInstance &CI = *interp.getCI();
1090 Preprocessor &PP = CI.getPreprocessor();
1091 auto ModuleManager = CI.getModuleManager();
1092 assert(ModuleManager);
1093 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1094 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1095 // HSI.setModuleCachePath(TROOT::GetLibDir().Data());
1096 std::string ModuleIndexPath = TROOT::GetLibDir().Data();
1097 if (ModuleIndexPath.empty())
1098 return nullptr;
1099 // Get an existing global index. This loads it if not already loaded.
1100 ModuleManager->resetForReload();
1101 ModuleManager->loadGlobalIndex();
1102 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1103
1104 // For finding modules needing to be imported for fixit messages,
1105 // we need to make the global index cover all modules, so we do that here.
1106 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1107 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1108 bool RecreateIndex = false;
1109 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1110 Module *TheModule = I->second;
1111 // We want the index only of the prebuilt modules.
1112 if (!HasASTFileOnDisk(TheModule, PP))
1113 continue;
1114 LoadModule(TheModule->Name, interp);
1115 RecreateIndex = true;
1116 }
1117 if (RecreateIndex) {
1118 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1119 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1120
1121 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1122 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1123 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1124 TraverseDecl(TU);
1125 }
1126 bool VisitNamedDecl(NamedDecl *ND) {
1127 if (!ND->isFromASTFile())
1128 return true;
1129 if (!ND->getIdentifier())
1130 return true;
1131
1132 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1133 return true;
1134
1135 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1136 if (TD->isCompleteDefinition())
1137 Register(TD);
1138 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1139 Register(NSD, /*AddSingleEntry=*/ false);
1140 }
1141 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1142 Register(TND);
1143 // FIXME: Add the rest...
1144 return true; // continue decending
1145 }
1146 private:
1147 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1148 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1149 assert(ND->isFromASTFile());
1150 // FIXME: All decls should have an owning module once rootcling
1151 // updates its generated decls from within the LookupHelper & co.
1152 if (!ND->hasOwningModule()) {
1153#ifndef NDEBUG
1154 SourceManager &SM = ND->getASTContext().getSourceManager();
1155 SourceLocation Loc = ND->getLocation();
1156 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1157 (void)FE;
1158 assert(FE->getName().contains("input_line_"));
1159#endif
1160 return;
1161 }
1162
1163 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1164 assert(OwningModule);
1165 assert(!ND->getName().empty() && "Empty name");
1166 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1167 return;
1168 // FIXME: The FileEntry in not stable to serialize.
1169 // FIXME: We might end up with many times with the same module.
1170 // FIXME: We might end up two modules containing a definition.
1171 // FIXME: What do we do if no definition is found.
1172 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1173 }
1174 };
1175 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1176
1177 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1178 CI.getPCHContainerReader(),
1179 ModuleIndexPath,
1180 &IDs));
1181 ModuleManager->resetForReload();
1182 ModuleManager->loadGlobalIndex();
1183 GlobalIndex = ModuleManager->getGlobalIndex();
1184 }
1186 }
1187 return GlobalIndex;
1188}
1189
1190static void RegisterCxxModules(cling::Interpreter &clingInterp)
1191{
1192 if (!clingInterp.getCI()->getLangOpts().Modules)
1193 return;
1194
1195 // Loading of a module might deserialize.
1196 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1197
1198 // Setup core C++ modules if we have any to setup.
1199
1200 // Load libc and stl first.
1201 // Load vcruntime module for windows
1202#ifdef R__WIN32
1203 LoadModule("vcruntime", clingInterp);
1204 LoadModule("services", clingInterp);
1205#endif
1206
1207#ifdef R__MACOSX
1208 LoadModule("Darwin", clingInterp);
1209#else
1210 LoadModule("libc", clingInterp);
1211#endif
1212 LoadModule("std", clingInterp);
1213
1214 LoadModule("_Builtin_intrinsics", clingInterp);
1215
1216 // Load core modules
1217 // This should be vector in order to be able to pass it to LoadModules
1218 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1219 "ROOT_Config",
1220 "ROOT_Rtypes",
1221 "ROOT_Foundation_Stage1_NoRTTI",
1222 "Core",
1223 "Rint",
1224 "RIO"};
1225
1226 LoadModules(CoreModules, clingInterp);
1227
1228 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1229 if (!IsFromRootCling()) {
1230 std::vector<std::string> CommonModules = {"MathCore"};
1231 LoadModules(CommonModules, clingInterp);
1232
1233 // These modules should not be preloaded but they fix issues.
1234 // FIXME: Hist is not a core module but is very entangled to MathCore and
1235 // causes issues.
1236 std::vector<std::string> FIXMEModules = {"Hist"};
1237 clang::CompilerInstance &CI = *clingInterp.getCI();
1238 clang::Preprocessor &PP = CI.getPreprocessor();
1239 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1240 if (MMap.findModule("RInterface"))
1241 FIXMEModules.push_back("RInterface");
1242
1243 LoadModules(FIXMEModules, clingInterp);
1244
1245 GlobalModuleIndex *GlobalIndex = nullptr;
1246 // Conservatively enable platform by platform.
1247 bool supportedPlatform =
1248#ifdef R__LINUX
1249 true
1250#elif defined(R__MACOSX)
1251 true
1252#else // Windows
1253 false
1254#endif
1255 ;
1256 // Allow forcefully enabling/disabling the GMI.
1257 llvm::Optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1258 if (envUseGMI.hasValue()) {
1259 if (!envUseGMI->empty() && !ROOT::FoundationUtils::CanConvertEnvValueToBool(*envUseGMI))
1260 ::Warning("TCling__RegisterCxxModules",
1261 "Cannot convert '%s' to bool, setting to false!",
1262 envUseGMI->c_str());
1263
1264 bool value = envUseGMI->empty() || ROOT::FoundationUtils::ConvertEnvValueToBool(*envUseGMI);
1265
1266 if (supportedPlatform == value)
1267 ::Warning("TCling__RegisterCxxModules", "Global module index is%sused already!",
1268 (value) ? " " :" not ");
1269 supportedPlatform = value;
1270 }
1271
1272 if (supportedPlatform) {
1273 loadGlobalModuleIndex(clingInterp);
1274 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1275 // We should investigate how to suppress it completely.
1276 GlobalIndex = CI.getModuleManager()->getGlobalIndex();
1277 }
1278
1279 llvm::StringSet<> KnownModuleFileNames;
1280 if (GlobalIndex)
1281 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1282
1283 std::vector<std::string> PendingModules;
1284 PendingModules.reserve(256);
1285 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1286 clang::Module *M = I->second;
1287 assert(M);
1288
1289 // We want to load only already created modules.
1290 std::string FullASTFilePath;
1291 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1292 continue;
1293
1294 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1295 continue;
1296
1297 if (M->IsMissingRequirement)
1298 continue;
1299
1300 if (GlobalIndex)
1301 LoadModule(M->Name, clingInterp);
1302 else {
1303 // FIXME: We may be able to remove those checks as cling::loadModule
1304 // checks if a module was alredy loaded.
1305 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1306 continue; // This is a core module which was already loaded.
1307
1308 // Load system modules now and delay the other modules after we have
1309 // loaded all system ones.
1310 if (M->IsSystem)
1311 LoadModule(M->Name, clingInterp);
1312 else
1313 PendingModules.push_back(M->Name);
1314 }
1315 }
1316 LoadModules(PendingModules, clingInterp);
1317 }
1318
1319 // Check that the gROOT macro was exported by any core module.
1320 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1321
1322 // `ERROR` and `PI` are from loading R related modules, which conflict with
1323 // user's code.
1324 clingInterp.declare(R"CODE(
1325#ifdef PI
1326# undef PI
1327#endif
1328#ifdef ERROR
1329# undef ERROR
1330#endif
1331 )CODE");
1332}
1333
1334static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1335{
1336 std::string PreIncludes;
1337 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1338
1339 // For the list to also include string, we have to include it now.
1340 // rootcling does parts already if needed, e.g. genreflex does not want using
1341 // namespace std.
1342 if (IsFromRootCling()) {
1343 PreIncludes += "#include \"RtypesCore.h\"\n";
1344 } else {
1345 if (!hasCxxModules)
1346 PreIncludes += "#include \"Rtypes.h\"\n";
1347
1348 PreIncludes += gClassDefInterpMacro + "\n"
1349 + gInterpreterClassDef + "\n"
1350 "#undef ClassImp\n"
1351 "#define ClassImp(X);\n";
1352 }
1353 if (!hasCxxModules)
1354 PreIncludes += "#include <string>\n";
1355
1356 // We must include it even when we have modules because it is marked as
1357 // textual in the modulemap due to the nature of the assert header.
1358#ifndef R__WIN32
1359 PreIncludes += "#include <cassert>\n";
1360#endif
1361 PreIncludes += "using namespace std;\n";
1362 clingInterp.declare(PreIncludes);
1363}
1364
1365////////////////////////////////////////////////////////////////////////////////
1366/// Initialize the cling interpreter interface.
1367/// \param argv - array of arguments passed to the cling::Interpreter constructor
1368/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1369
1370TCling::TCling(const char *name, const char *title, const char* const argv[])
1371: TInterpreter(name, title), fMore(0), fGlobalsListSerial(-1), fMapfile(nullptr),
1375{
1376 fPrompt[0] = 0;
1377 const bool fromRootCling = IsFromRootCling();
1378
1379 fCxxModulesEnabled = false;
1380#ifdef R__USE_CXXMODULES
1381 fCxxModulesEnabled = true;
1382#endif
1383
1384 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1385
1386 fTemporaries = new std::vector<cling::Value>();
1387
1388 std::vector<std::string> clingArgsStorage;
1389 clingArgsStorage.push_back("cling4root");
1390 for (const char* const* arg = argv; *arg; ++arg)
1391 clingArgsStorage.push_back(*arg);
1392
1393 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1394 if (!fromRootCling) {
1396
1397 // Add -I early so ASTReader can find the headers.
1398 std::string interpInclude(TROOT::GetEtcDir().Data());
1399 clingArgsStorage.push_back("-I" + interpInclude);
1400
1401 // Add include path to etc/cling.
1402 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1403
1404 // Add include path to etc/cling.
1405 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1406
1407 // Add the root include directory and etc/ to list searched by default.
1408 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1409
1410 // Add the current path to the include path
1411 // TCling::AddIncludePath(".");
1412
1413 // Attach the PCH (unless we have C++ modules enabled which provide the
1414 // same functionality).
1415 if (!fCxxModulesEnabled) {
1416 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1417 if (gSystem->Getenv("ROOT_PCH")) {
1418 pchFilename = gSystem->Getenv("ROOT_PCH");
1419 }
1420
1421 clingArgsStorage.push_back("-include-pch");
1422 clingArgsStorage.push_back(pchFilename);
1423 }
1424
1425 clingArgsStorage.push_back("-Wno-undefined-inline");
1426 clingArgsStorage.push_back("-fsigned-char");
1427 clingArgsStorage.push_back("-O1");
1428 // Disable optimized register allocation which is turned on automatically
1429 // by -O1, but seems to require -O2 to not explode in run time.
1430 clingArgsStorage.push_back("-mllvm");
1431 clingArgsStorage.push_back("-optimize-regalloc=0");
1432 }
1433
1434 // Process externally passed arguments if present.
1435 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1436 if (EnvOpt.hasValue()) {
1437 StringRef Env(*EnvOpt);
1438 while (!Env.empty()) {
1439 StringRef Arg;
1440 std::tie(Arg, Env) = Env.split(' ');
1441 clingArgsStorage.push_back(Arg.str());
1442 }
1443 }
1444
1445 auto GetEnvVarPath = [](const std::string &EnvVar,
1446 std::vector<std::string> &Paths) {
1447 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1448 if (EnvOpt.hasValue()) {
1449 StringRef Env(*EnvOpt);
1450 while (!Env.empty()) {
1451 StringRef Arg;
1452 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1453 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1454 Paths.push_back(Arg.str());
1455 }
1456 }
1457 };
1458
1459 if (fCxxModulesEnabled) {
1460 std::vector<std::string> Paths;
1461 // ROOT usually knows better where its libraries are. This way we can
1462 // discover modules without having to should thisroot.sh and should fix
1463 // gnuinstall.
1464#ifdef R__WIN32
1465 Paths.push_back(TROOT::GetBinDir().Data());
1466#else
1467 Paths.push_back(TROOT::GetLibDir().Data());
1468#endif
1469 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1470 std::string EnvVarPath;
1471 for (const std::string& P : Paths)
1473 // FIXME: We should make cling -fprebuilt-module-path work.
1474 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1475 }
1476
1477 // FIXME: This only will enable frontend timing reports.
1478 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1479 if (EnvOpt.hasValue())
1480 clingArgsStorage.push_back("-ftime-report");
1481
1482 // Add the overlay file. Note that we cannot factor it out for both root
1483 // and rootcling because rootcling activates modules only if -cxxmodule
1484 // flag is passed.
1485 if (fCxxModulesEnabled && !fromRootCling) {
1486 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1487 std::vector<std::string> ModuleMaps;
1488 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "module.modulemap";
1489 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1490 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1491
1492 std::string cwd = gSystem->WorkingDirectory();
1493 // Give highest precedence of the modulemap in the cwd if any.
1494 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1495 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1496
1497 for (const std::string& M : ModuleMaps)
1498 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1499
1500 std::string ModulesCachePath;
1501 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1502 if (EnvOpt.hasValue()){
1503 StringRef Env(*EnvOpt);
1504 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1505 ModulesCachePath = Env.str();
1506 } else {
1507 ModulesCachePath = TROOT::GetLibDir();
1508 }
1509
1510 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1511 }
1512
1513 std::vector<const char*> interpArgs;
1514 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1515 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1516 interpArgs.push_back(iArg->c_str());
1517
1518 // Activate C++ modules support. If we are running within rootcling, it's up
1519 // to rootcling to set this flag depending on whether it wants to produce
1520 // C++ modules.
1521 TString vfsArg;
1522 if (fCxxModulesEnabled) {
1523 if (!fromRootCling) {
1524 // We only set this flag, rest is done by the CIFactory.
1525 interpArgs.push_back("-fmodules");
1526 interpArgs.push_back("-fno-implicit-module-maps");
1527 // We should never build modules during runtime, so let's enable the
1528 // module build remarks from clang to make it easier to spot when we do
1529 // this by accident.
1530 interpArgs.push_back("-Rmodule-build");
1531 }
1532 // ROOT implements its AutoLoading upon module's link directives. We
1533 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1534 // facilities use the link directive to dynamically load the relevant
1535 // library. So, we need to suppress clang's default autolink behavior.
1536 interpArgs.push_back("-fno-autolink");
1537 }
1538
1539#ifdef R__FAST_MATH
1540 // Same setting as in rootcling_impl.cxx.
1541 interpArgs.push_back("-ffast-math");
1542#endif
1543
1544 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1545 // Add statically injected extra arguments, usually coming from rootcling.
1546 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1547 extraArgs && *extraArgs; ++extraArgs) {
1548 if (!strcmp(*extraArgs, "-resource-dir")) {
1549 // Take the next arg as the llvm resource directory.
1550 llvmResourceDir = *(++extraArgs);
1551 } else {
1552 interpArgs.push_back(*extraArgs);
1553 }
1554 }
1555
1556 for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1557 interpArgs.push_back(arg.c_str());
1558 }
1559
1560 // Add the Rdict module file extension.
1561 cling::Interpreter::ModuleFileExtensions extensions;
1562 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1563 if (!EnvOpt.hasValue())
1564 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1565
1566 fInterpreter = llvm::make_unique<cling::Interpreter>(interpArgs.size(),
1567 &(interpArgs[0]),
1568 llvmResourceDir, extensions);
1569
1570 // Don't check whether modules' files exist.
1571 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
1572
1573 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1574 // to disable spell checking.
1575 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1576
1577 // We need stream that doesn't close its file descriptor, thus we are not
1578 // using llvm::outs. Keeping file descriptor open we will be able to use
1579 // the results in pipes (Savannah #99234).
1580 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1581 fMetaProcessor = llvm::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1582
1585
1586 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1593
1594 // Disallow auto-parsing in rootcling
1595 fIsAutoParsingSuspended = fromRootCling;
1596
1597 ResetAll();
1598
1599 // Enable dynamic lookup
1600 if (!fromRootCling) {
1601 fInterpreter->enableDynamicLookup();
1602 }
1603
1604 // Enable ClinG's DefinitionShadower for ROOT.
1605 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1606
1607 // Attach cling callbacks last; they might need TROOT::fInterpreter
1608 // and should thus not be triggered during the equivalent of
1609 // TROOT::fInterpreter = new TCling;
1610 std::unique_ptr<TClingCallbacks>
1611 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1612 fClingCallbacks = clingCallbacks.get();
1614 fInterpreter->setCallbacks(std::move(clingCallbacks));
1615
1616 if (!fromRootCling) {
1617 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1618 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1619 // e.g. because of an RPATH build.
1620 DLM.addSearchPath(TROOT::GetLibDir().Data(), /*isUser=*/true,
1621 /*prepend=*/true);
1622 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1623 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1624 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1625 };
1626 // Initialize the dyld for the llvmLazyFunctionCreator.
1627 DLM.initializeDyld(ShouldPermanentlyIgnore);
1628 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1629 }
1630}
1631
1632
1633////////////////////////////////////////////////////////////////////////////////
1634/// Destroy the interpreter interface.
1635
1637{
1638 // ROOT's atexit functions require the interepreter to be available.
1639 // Run them before shutting down.
1640 if (!IsFromRootCling())
1641 GetInterpreterImpl()->runAtExitFuncs();
1642 fIsShuttingDown = true;
1643 delete fMapfile;
1644 delete fRootmapFiles;
1645 delete fTemporaries;
1646 delete fNormalizedCtxt;
1647 delete fLookupHelper;
1648 gCling = 0;
1649}
1650
1651////////////////////////////////////////////////////////////////////////////////
1652/// Initialize the interpreter, once TROOT::fInterpreter is set.
1653
1655{
1657
1658 // We are set up. Enable ROOT's AutoLoading.
1659 if (IsFromRootCling())
1660 return;
1661
1662 // Read the rules before enabling the auto loading to not inadvertently
1663 // load the libraries for the classes concerned even-though the user is
1664 // *not* using them.
1665 // Note this call must happen before the first call to LoadLibraryMap.
1666 assert(GetRootMapFiles() == 0 && "Must be called before LoadLibraryMap!");
1667 TClass::ReadRules(); // Read the default customization rules ...
1668
1670 SetClassAutoLoading(true);
1671}
1672
1674{
1675 fIsShuttingDown = true;
1676 ResetGlobals();
1677}
1678
1679////////////////////////////////////////////////////////////////////////////////
1680/// Helper to initialize TVirtualStreamerInfo's factor early.
1681/// Use static initialization to insure only one TStreamerInfo is created.
1683{
1684 // Use lambda since SetFactory return void.
1685 auto setFactory = []() {
1687 return kTRUE;
1688 };
1689 static bool doneFactory = setFactory();
1690 return doneFactory; // avoid unused variable warning.
1691}
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Register Rdict data for future loading by LoadPCM;
1695
1696void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1697{
1698 if (IsFromRootCling())
1699 return;
1700
1701 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1702 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1703 return;
1704 }
1705
1706 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1707 // a link to a non-existent file.
1708 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1709}
1710
1711////////////////////////////////////////////////////////////////////////////////
1712/// Tries to load a PCM from TFile; returns true on success.
1713
1715{
1716 auto listOfKeys = pcmFile.GetListOfKeys();
1717
1718 // This is an empty pcm
1719 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1720 ((listOfKeys->GetSize() == 1) && // only one, and
1721 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1722 ))) {
1723 return;
1724 }
1725
1726 TObjArray *protoClasses;
1727 if (gDebug > 1)
1728 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1729
1730 TObjArray *enums;
1731 pcmFile.GetObject("__Enums", enums);
1732 if (enums) {
1733 // Cache the pointers
1734 auto listOfGlobals = gROOT->GetListOfGlobals();
1735 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1736 // Loop on enums and then on enum constants
1737 for (auto selEnum : *enums) {
1738 const char *enumScope = selEnum->GetTitle();
1739 const char *enumName = selEnum->GetName();
1740 if (strcmp(enumScope, "") == 0) {
1741 // This is a global enum and is added to the
1742 // list of enums and its constants to the list of globals
1743 if (!listOfEnums->THashList::FindObject(enumName)) {
1744 ((TEnum *)selEnum)->SetClass(nullptr);
1745 listOfEnums->Add(selEnum);
1746 }
1747 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1748 if (!listOfGlobals->FindObject(enumConstant)) {
1749 listOfGlobals->Add(enumConstant);
1750 }
1751 }
1752 } else {
1753 // This enum is in a namespace. A TClass entry is bootstrapped if
1754 // none exists yet and the enum is added to it
1755 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1756 if (!nsTClassEntry) {
1757 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1758 }
1759 auto listOfEnums = nsTClassEntry->fEnums.load();
1760 if (!listOfEnums) {
1761 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1762 // For this case, the list will be immutable once constructed
1763 // (i.e. in this case, by the end of this routine).
1764 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1765 } else {
1766 // namespaces can have enums added to them
1767 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1768 }
1769 }
1770 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1771 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1772 listOfEnums->Add(selEnum);
1773 }
1774 }
1775 }
1776 enums->Clear();
1777 delete enums;
1778 }
1779
1780 pcmFile.GetObject("__ProtoClasses", protoClasses);
1781
1782 if (protoClasses) {
1783 for (auto obj : *protoClasses) {
1784 TProtoClass *proto = (TProtoClass *)obj;
1786 }
1787 // Now that all TClass-es know how to set them up we can update
1788 // existing TClasses, which might cause the creation of e.g. TBaseClass
1789 // objects which in turn requires the creation of TClasses, that could
1790 // come from the PCH, but maybe later in the loop. Instead of resolving
1791 // a dependency graph the addition to the TClassTable above allows us
1792 // to create these dependent TClasses as needed below.
1793 for (auto proto : *protoClasses) {
1794 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1795 // We have an existing TClass object. It might be emulated
1796 // or interpreted; we now have more information available.
1797 // Make that available.
1798 if (existingCl->GetState() != TClass::kHasTClassInit) {
1799 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1800 if (!dict) {
1801 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1802 } else {
1803 // This will replace the existing TClass.
1804 TClass *ncl = (*dict)();
1805 if (ncl)
1806 ncl->PostLoadCheck();
1807 }
1808 }
1809 }
1810 }
1811
1812 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1813 delete protoClasses;
1814 }
1815
1816 TObjArray *dataTypes;
1817 pcmFile.GetObject("__Typedefs", dataTypes);
1818 if (dataTypes) {
1819 for (auto typedf : *dataTypes)
1820 gROOT->GetListOfTypes()->Add(typedf);
1821 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1822 delete dataTypes;
1823 }
1824}
1825
1826////////////////////////////////////////////////////////////////////////////////
1827/// Tries to load a rdict PCM, issues diagnostics if it fails.
1828
1829void TCling::LoadPCM(std::string pcmFileNameFullPath)
1830{
1831 SuspendAutoLoadingRAII autoloadOff(this);
1832 SuspendAutoParsing autoparseOff(this);
1833 assert(!pcmFileNameFullPath.empty());
1834 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1835
1836 // Easier to work with the ROOT interfaces.
1837 TString pcmFileName = pcmFileNameFullPath;
1838
1839 // Prevent the ROOT-PCMs hitting this during auto-load during
1840 // JITting - which will cause recursive compilation.
1841 // Avoid to call the plugin manager at all.
1843
1845 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1846 if (gDebug > 5) {
1847 gDebug -= 5;
1848 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1849 } else {
1850 gDebug = 0;
1851 }
1852
1853 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1854 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1855
1856 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1857 if (pendingRdict != fPendingRdicts.end()) {
1858 llvm::StringRef pcmContent = pendingRdict->second;
1859 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1860 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1861 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1862
1863 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1864 LoadPCMImpl(pcmMemFile);
1865 fPendingRdicts.erase(pendingRdict);
1866
1867 return;
1868 }
1869
1870 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1871 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1872 pcmFileNameFullPath.data());
1873 if (!fPendingRdicts.empty())
1874 for (const auto &rdict : fPendingRdicts)
1875 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1876 rdict.first.c_str());
1877 return;
1878 }
1879
1880 if (!gROOT->IsRootFile(pcmFileName)) {
1881 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1882 return;
1883 }
1884 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1885 LoadPCMImpl(pcmFile);
1886}
1887
1888//______________________________________________________________________________
1889
1890namespace {
1891 using namespace clang;
1892
1893 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1894 // This class is to be considered an helper for autoparsing.
1895 // It visits the AST and marks all classes (in all of their redeclarations)
1896 // with the setHasExternalLexicalStorage method.
1897 public:
1898 bool VisitRecordDecl(clang::RecordDecl* rcd){
1899 if (gDebug > 2)
1900 Info("ExtLexicalStorageAdder",
1901 "Adding external lexical storage to class %s",
1902 rcd->getNameAsString().c_str());
1903 auto reDeclPtr = rcd->getMostRecentDecl();
1904 do {
1905 reDeclPtr->setHasExternalLexicalStorage();
1906 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1907
1908 return false;
1909 }
1910 };
1911
1912
1913}
1914
1915////////////////////////////////////////////////////////////////////////////////
1916///\returns true if the module map was loaded, false on error or if the map was
1917/// already loaded.
1918bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1919 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1920{
1921 assert(llvm::sys::path::is_absolute(FullPath));
1922 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1923 FileManager &FM = PP.getFileManager();
1924 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1925 // We should look for modulemap files there too.
1926 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1927 if (DE) {
1928 HeaderSearch &HS = PP.getHeaderSearchInfo();
1929 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1930 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1931 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1932 if (!pathExists)
1933 HSOpts.AddPrebuiltModulePath(FullPath);
1934 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1935 // because its internal call to getFile has CacheFailure set to true.
1936 // In our case, modulemaps can appear any time due to ACLiC.
1937 // Code copied from HS.lookupModuleMapFile.
1938 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1939 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1940 const FileEntry *FE = FM.getFile(ModuleMapFileName, /*openFile*/ false,
1941 /*CacheFailure*/ false);
1942 if (FE) {
1943 if (!HS.loadModuleMapFile(FE, /*IsSystem*/ false))
1944 return true;
1945 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1946 }
1947 }
1948 return false;
1949}
1950
1951////////////////////////////////////////////////////////////////////////////////
1952/// List of dicts that have the PCM information already in the PCH.
1953static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1954 "libRint",
1955 "libThread",
1956 "libRIO",
1957 "libImt",
1958 "libMultiProc",
1959 "libcomplexDict",
1960 "libdequeDict",
1961 "liblistDict",
1962 "libforward_listDict",
1963 "libvectorDict",
1964 "libmapDict",
1965 "libmultimap2Dict",
1966 "libmap2Dict",
1967 "libmultimapDict",
1968 "libsetDict",
1969 "libmultisetDict",
1970 "libunordered_setDict",
1971 "libunordered_multisetDict",
1972 "libunordered_mapDict",
1973 "libunordered_multimapDict",
1974 "libvalarrayDict",
1975 "G__GenVector32",
1976 "G__Smatrix32"};
1977
1978static void PrintDlError(const char *dyLibName, const char *modulename)
1979{
1980#ifdef R__WIN32
1981 char dyLibError[1000];
1982 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1983 dyLibError, sizeof(dyLibError), NULL);
1984#else
1985 const char *dyLibError = dlerror();
1986#endif
1987 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1988 (dyLibError) ? dyLibError : "");
1989}
1990
1991////////////////////////////////////////////////////////////////////////////////
1992// Update all the TClass registered in fClassesToUpdate
1993
1995{
1996 while (!fClassesToUpdate.empty()) {
1997 TClass *oldcl = fClassesToUpdate.back().first;
1998 // If somehow the TClass has already been loaded (maybe it was registered several time),
1999 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2000 // maybe even kForwardDeclared and needs to replaced.
2001 if (oldcl->GetState() != TClass::kHasTClassInit) {
2002 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2003 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2004 fClassesToUpdate.pop_back();
2005 // Calling func could manipulate the list so, let maintain the list
2006 // then call the dictionary function.
2007 TClass *ncl = dict();
2008 if (ncl) ncl->PostLoadCheck();
2009 } else {
2010 fClassesToUpdate.pop_back();
2011 }
2012 }
2013}
2014////////////////////////////////////////////////////////////////////////////////
2015/// Inject the module named "modulename" into cling; load all headers.
2016/// headers is a 0-terminated array of header files to #include after
2017/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2018/// entries (or %PATH% on Windows).
2019/// This function gets called by the static initialization of dictionary
2020/// libraries.
2021/// The payload code is injected "as is" in the interpreter.
2022/// The value of 'triggerFunc' is used to find the shared library location.
2023
2024void TCling::RegisterModule(const char* modulename,
2025 const char** headers,
2026 const char** includePaths,
2027 const char* payloadCode,
2028 const char* fwdDeclsCode,
2029 void (*triggerFunc)(),
2030 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2031 const char** classesHeaders,
2032 Bool_t lateRegistration /*=false*/,
2033 Bool_t hasCxxModule /*=false*/)
2034{
2035 const bool fromRootCling = IsFromRootCling();
2036 // We need the dictionary initialization but we don't want to inject the
2037 // declarations into the interpreter, except for those we really need for
2038 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2039 if (fromRootCling) return;
2040
2041 // When we cannot provide a module for the library we should enable header
2042 // parsing. This 'mixed' mode ensures gradual migration to modules.
2043 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2044 fHeaderParsingOnDemand = !hasCxxModule;
2045
2046 // Treat Aclic Libs in a special way. Do not delay the parsing.
2047 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2048 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2049 if (hasHeaderParsingOnDemand && isACLiC) {
2050 if (gDebug>1)
2051 Info("TCling::RegisterModule",
2052 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2053 hasHeaderParsingOnDemand = false;
2054 }
2055
2056
2057 // Make sure we relookup symbols that were search for before we loaded
2058 // their autoparse information. We could be more subtil and remove only
2059 // the failed one or only the one in this module, but for now this is
2060 // better than nothing.
2061 fLookedUpClasses.clear();
2062
2063 // Make sure we do not set off AutoLoading or autoparsing during the
2064 // module registration!
2065 SuspendAutoLoadingRAII autoLoadOff(this);
2066
2067 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2068 TCling::AddIncludePath(*inclPath);
2069 }
2070 cling::Transaction* T = 0;
2071 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2072 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2073 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2074 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2075 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2076 assert(cling::Interpreter::kSuccess == compRes &&
2077 "A fwd declaration could not be compiled");
2078 if (compRes!=cling::Interpreter::kSuccess){
2079 Warning("TCling::RegisterModule",
2080 "Problems in declaring string '%s' were encountered.",
2081 fwdDecl.c_str()) ;
2082 continue;
2083 }
2084
2085 // Drill through namespaces recursively until the template is found
2086 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2087 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2088 }
2089
2090 }
2091
2092 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2093 // This is used to give Sema the same view on ACLiC'ed files (which
2094 // are then #included through the dictionary) as rootcling had.
2095 TString code = gNonInterpreterClassDef;
2096 if (payloadCode)
2097 code += payloadCode;
2098
2099 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2100 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2101
2102 if (dyLibName.empty()) {
2103 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2104 return;
2105 }
2106
2107 // The triggerFunc may not be in a shared object but in an executable.
2108 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2109
2110 bool wasDlopened = false;
2111
2112 // If this call happens after dlopen has finished (i.e. late registration)
2113 // there is no need to dlopen the library recursively. See ROOT-8437 where
2114 // the dyLibName would correspond to the binary.
2115 if (!lateRegistration) {
2116
2117 if (isSharedLib) {
2118 // We need to open the dictionary shared library, to resolve symbols
2119 // requested by the JIT from it: as the library is currently being dlopen'ed,
2120 // its symbols are not yet reachable from the process.
2121 // Recursive dlopen seems to work just fine.
2122 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2123 if (dyLibHandle) {
2124 fRegisterModuleDyLibs.push_back(dyLibHandle);
2125 wasDlopened = true;
2126 } else {
2127 PrintDlError(dyLibName.c_str(), modulename);
2128 }
2129 }
2130 } // if (!lateRegistration)
2131
2132 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2133 // We now parse the forward declarations. All the classes are then modified
2134 // in order for them to have an external lexical storage.
2135 std::string fwdDeclsCodeLessEnums;
2136 {
2137 // Search for enum forward decls and only declare them if no
2138 // declaration exists yet.
2139 std::string fwdDeclsLine;
2140 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2141 std::vector<std::string> scopes;
2142 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2143 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2144 // We check if the line contains a fwd declaration of an enum
2145 if (enumPos != std::string::npos) {
2146 // We clear the scopes which we may have carried from a previous iteration
2147 scopes.clear();
2148 // We check if the enum is not in a scope. If yes, save its name
2149 // and the names of the enclosing scopes.
2150 if (enumPos != 0) {
2151 // it's enclosed in namespaces. We need to understand what they are
2152 auto nsPos = fwdDeclsLine.find("namespace");
2153 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2154 while (nsPos < enumPos && nsPos != std::string::npos) {
2155 // we have a namespace, let's put it in the collection of scopes
2156 const auto nsNameStart = nsPos + 10;
2157 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2158 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2159 scopes.push_back(nsName);
2160 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2161 }
2162 }
2163 clang::DeclContext* DC = 0;
2164 for (auto &&aScope: scopes) {
2165 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2166 if (!DC) {
2167 // No decl context means we have to fwd declare the enum.
2168 break;
2169 }
2170 }
2171 if (scopes.empty() || DC) {
2172 // We know the scope; let's look for the enum. For that, look
2173 // for the *last* closing parentheses of an attribute because
2174 // there can be multiple.
2175 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2176 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2177 posEnumName += 5; // skip "\"))) "
2178 while (isspace(fwdDeclsLine[posEnumName]))
2179 ++posEnumName;
2180 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2181 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2182 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2183 --posEnumNameEnd;
2184 // posEnumNameEnd now points to the last character of the name.
2185
2186 std::string enumName = fwdDeclsLine.substr(posEnumName,
2187 posEnumNameEnd - posEnumName + 1);
2188
2189 if (clang::NamedDecl* enumDecl
2190 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2191 enumName.c_str(), DC)) {
2192 // We have an existing enum decl (forward or definition);
2193 // skip this.
2194 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2195 (void)enumDecl;
2196 continue;
2197 }
2198 }
2199 }
2200
2201 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2202 }
2203 }
2204
2205 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2206 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2207 assert(cling::Interpreter::kSuccess == compRes &&
2208 "The forward declarations could not be compiled");
2209 if (compRes!=cling::Interpreter::kSuccess){
2210 Warning("TCling::RegisterModule",
2211 "Problems in compiling forward declarations for module %s: '%s'",
2212 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2213 }
2214 else if (T){
2215 // Loop over all decls in the transaction and go through them all
2216 // to mark them properly.
2217 // In order to do that, we first iterate over all the DelayedCallInfos
2218 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2219 // contained in the DelayedCallInfos. For each decl, we traverse.
2220 ExtLexicalStorageAdder elsa;
2221 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2222 cling::Transaction::DelayCallInfo& dci = *dciIt;
2223 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2224 clang::Decl* declPtr = *dit;
2225 elsa.TraverseDecl(declPtr);
2226 }
2227 }
2228 }
2229 }
2230
2231 // Now we register all the headers necessary for the class
2232 // Typical format of the array:
2233 // {"A", "classes.h", "@",
2234 // "vector<A>", "vector", "@",
2235 // "myClass", payloadCode, "@",
2236 // nullptr};
2237
2238 std::string temp;
2239 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2240 temp=*classesHeader;
2241
2242 size_t theTemplateHash = 0;
2243 bool addTemplate = false;
2244 size_t posTemplate = temp.find('<');
2245 if (posTemplate != std::string::npos) {
2246 // Add an entry for the template itself.
2247 std::string templateName = temp.substr(0, posTemplate);
2248 theTemplateHash = fStringHashFunction(templateName);
2249 addTemplate = true;
2250 }
2251 size_t theHash = fStringHashFunction(temp);
2252 classesHeader++;
2253 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2254 // This is done in order to distinguish headers from files and from the payloadCode
2255 if (payloadCode == *classesHeader_inner ){
2256 fPayloads.insert(theHash);
2257 if (addTemplate) fPayloads.insert(theTemplateHash);
2258 }
2259 if (gDebug > 2)
2260 Info("TCling::RegisterModule",
2261 "Adding a header for %s", temp.c_str());
2262 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2263 if (addTemplate) {
2264 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2265 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2266 }
2267 addTemplate = false;
2268 }
2269 }
2270 }
2271 }
2272
2273 clang::Sema &TheSema = fInterpreter->getSema();
2274
2275 bool ModuleWasSuccessfullyLoaded = false;
2276 if (hasCxxModule) {
2277 std::string ModuleName = modulename;
2278 if (llvm::StringRef(modulename).startswith("lib"))
2279 ModuleName = llvm::StringRef(modulename).substr(3).str();
2280
2281 // In case we are directly loading the library via gSystem->Load() without
2282 // specifying the relevant include paths we should try loading the
2283 // modulemap next to the library location.
2284 clang::Preprocessor &PP = TheSema.getPreprocessor();
2285 std::string ModuleMapName;
2286 if (isACLiC)
2287 ModuleMapName = ModuleName + ".modulemap";
2288 else
2289 ModuleMapName = "module.modulemap";
2290 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName),
2291 ModuleMapName);
2292
2293 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2294 // modules such as GenVector32 because it needs to fall back to GenVector.
2295 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2296 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2297 if (!ModuleWasSuccessfullyLoaded) {
2298 // Only report if we found the module in the modulemap.
2299 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2300 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2301 if (moduleMap.findModule(ModuleName))
2302 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2303 }
2304 }
2305
2306 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2307 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2308 // The path dyLibName might not be absolute. This can happen if dyLibName
2309 // is linked to an executable in the same folder.
2310 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2311 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2312 llvm::sys::path::append(pcmFileNameFullPath,
2314 LoadPCM(pcmFileNameFullPath.str().str());
2315 }
2316
2317 { // scope within which diagnostics are de-activated
2318 // For now we disable diagnostics because we saw them already at
2319 // dictionary generation time. That won't be an issue with the PCMs.
2320
2321 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2322
2323#if defined(R__MUST_REVISIT)
2324#if R__MUST_REVISIT(6,2)
2325 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2326#endif
2327#endif
2328
2329 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2330 SuspendAutoParsing autoParseRaii(this);
2331
2332 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2333 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2334 if (isACLiC) {
2335 // Register an unload point.
2336 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2337 }
2338
2339 assert(cling::Interpreter::kSuccess == compRes &&
2340 "Payload code of a dictionary could not be parsed correctly.");
2341 if (compRes!=cling::Interpreter::kSuccess) {
2342 Warning("TCling::RegisterModule",
2343 "Problems declaring payload for module %s.", modulename) ;
2344 }
2345 }
2346 }
2347
2348 // Now that all the header have been registered/compiled, let's
2349 // make sure to 'reset' the TClass that have a class init in this module
2350 // but already had their type information available (using information/header
2351 // loaded from other modules or from class rules or from opening a TFile
2352 // or from loading header in a way that did not provoke the loading of
2353 // the library we just loaded).
2355
2356 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2357 // __ROOTCLING__ might be pulled in through PCH
2358 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2359 "#undef __ROOTCLING__\n"
2360 + gInterpreterClassDef +
2361 "#endif");
2362 }
2363
2364 if (wasDlopened) {
2365 assert(isSharedLib);
2366 void* dyLibHandle = fRegisterModuleDyLibs.back();
2367 fRegisterModuleDyLibs.pop_back();
2368 dlclose(dyLibHandle);
2369 }
2370}
2371
2373 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2374 ASTContext &C = CI.getASTContext();
2375
2376 // Do not do anything if we have no global module index.
2377 // FIXME: This is mostly to real with false positives in the TTabCom
2378 // interface for non-modules.
2379 if (!fCxxModulesEnabled)
2380 return;
2381
2382 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2383 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2384 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2385 std::string I = Ident.str();
2386 if (!Idents.Contains(I.data()))
2387 Idents.Add(new TObjString(I.c_str()));
2388 }
2389 }
2390}
2391
2392
2393////////////////////////////////////////////////////////////////////////////////
2394/// Register classes that already existed prior to their dictionary loading
2395/// and that already had a ClassInfo (and thus would not be refresh via
2396/// UpdateClassInfo.
2397
2399{
2400 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2401}
2402
2403////////////////////////////////////////////////////////////////////////////////
2404/// If the dictionary is loaded, we can remove the class from the list
2405/// (otherwise the class might be loaded twice).
2406
2408{
2409 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2410 iterator stop = fClassesToUpdate.end();
2411 for(iterator i = fClassesToUpdate.begin();
2412 i != stop;
2413 ++i)
2414 {
2415 if ( i->first == oldcl ) {
2416 fClassesToUpdate.erase(i);
2417 return;
2418 }
2419 }
2420}
2421
2422
2423////////////////////////////////////////////////////////////////////////////////
2424/// Let cling process a command line.
2425///
2426/// If the command is executed and the error is 0, then the return value
2427/// is the int value corresponding to the result of the executed command
2428/// (float and double return values will be truncated).
2429///
2430
2431// Method for handling the interpreter exceptions.
2432// the MetaProcessor is passing in as argument to teh function, because
2433// cling::Interpreter::CompilationResult is a nested class and it cannot be
2434// forward declared, thus this method cannot be a static member function
2435// of TCling.
2436
2437static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2438 const char* input_line,
2439 cling::Interpreter::CompilationResult& compRes,
2440 cling::Value* result)
2441{
2442 try {
2443 return metaProcessor->process(input_line, compRes, result);
2444 }
2445 catch (cling::InterpreterException& ex)
2446 {
2447 Error("HandleInterpreterException", "%s.\n%s", ex.what(), "Execution of your code was aborted.");
2448 ex.diagnose();
2449 compRes = cling::Interpreter::kFailure;
2450 }
2451 return 0;
2452}
2453
2454////////////////////////////////////////////////////////////////////////////////
2455
2456bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2457{
2458 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2459 ie->diagnose();
2460 return true;
2461 }
2462 return false;
2463}
2464
2465////////////////////////////////////////////////////////////////////////////////
2466
2468{
2469 // Copy the passed line, it comes from a static buffer in TApplication
2470 // which can be reentered through the Cling evaluation routines,
2471 // which would overwrite the static buffer and we would forget what we
2472 // were doing.
2473 //
2474 TString sLine(line);
2475 if (strstr(line,fantomline)) {
2476 // End-Of-Line action
2477 // See the comment (copied from above):
2478 // It is a "fantom" method to synchronize user keyboard input
2479 // and ROOT prompt line (for WIN32)
2480 // and is implemented by
2481 if (gApplication) {
2482 if (gApplication->IsCmdThread()) {
2484 gROOT->SetLineIsProcessing();
2485
2487
2488 gROOT->SetLineHasBeenProcessed();
2489 }
2490 }
2491 return 0;
2492 }
2493
2495 gGlobalMutex->Lock();
2496 if (!gInterpreterMutex)
2499 }
2501 gROOT->SetLineIsProcessing();
2502
2503 struct InterpreterFlagsRAII {
2504 cling::Interpreter* fInterpreter;
2505 bool fWasDynamicLookupEnabled;
2506
2507 InterpreterFlagsRAII(cling::Interpreter* interp):
2508 fInterpreter(interp),
2509 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2510 {
2511 fInterpreter->enableDynamicLookup(true);
2512 }
2513 ~InterpreterFlagsRAII() {
2514 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2515 gROOT->SetLineHasBeenProcessed();
2516 }
2517 } interpreterFlagsRAII(GetInterpreterImpl());
2518
2519 // A non-zero returned value means the given line was
2520 // not a complete statement.
2521 int indent = 0;
2522 // This will hold the resulting value of the evaluation the given line.
2523 cling::Value result;
2524 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2525 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2526 !strncmp(sLine.Data(), ".X", 2)) {
2527 // If there was a trailing "+", then CINT compiled the code above,
2528 // and we will need to strip the "+" before passing the line to cling.
2529 TString mod_line(sLine);
2530 TString aclicMode;
2531 TString arguments;
2532 TString io;
2533 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2534 aclicMode, arguments, io);
2535 if (aclicMode.Length()) {
2536 // Remove the leading '+'
2537 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2538 aclicMode[0]='k'; // We always want to keep the .so around.
2539 if (aclicMode[1]=='+') {
2540 // We have a 2nd +
2541 aclicMode[1]='f'; // We want to force the recompilation.
2542 }
2543 if (!gSystem->CompileMacro(fname,aclicMode)) {
2544 // ACLiC failed.
2545 compRes = cling::Interpreter::kFailure;
2546 } else {
2547 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2548 // if execution was requested.
2549
2550 if (arguments.Length()==0) {
2551 arguments = "()";
2552 }
2553 // We need to remove the extension.
2554 Ssiz_t ext = fname.Last('.');
2555 if (ext != kNPOS) {
2556 fname.Remove(ext);
2557 }
2558 const char *function = gSystem->BaseName(fname);
2559 mod_line = function + arguments + io;
2560 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2561 }
2562 }
2563 } else {
2564 // not ACLiC
2565 size_t unnamedMacroOpenCurly;
2566 {
2567 std::string code;
2568 std::string codeline;
2569 // Windows requires std::ifstream::binary to properly handle
2570 // CRLF and LF line endings
2571 std::ifstream in(fname, std::ifstream::binary);
2572 while (in) {
2573 std::getline(in, codeline);
2574 code += codeline + "\n";
2575 }
2576 unnamedMacroOpenCurly
2577 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2578 }
2579
2580 fCurExecutingMacros.push_back(fname);
2581 if (unnamedMacroOpenCurly != std::string::npos) {
2582 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2583 unnamedMacroOpenCurly);
2584 } else {
2585 // No DynLookup for .x, .L of named macros.
2586 fInterpreter->enableDynamicLookup(false);
2587 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2588 }
2589 fCurExecutingMacros.pop_back();
2590 }
2591 } // .L / .X / .x
2592 else {
2593 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2594 // explicitly ignore .autodict without having to support it
2595 // in cling.
2596
2597 // Turn off autoparsing if this is an include directive
2598 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2599 if (isInclusionDirective) {
2600 SuspendAutoParsing autoParseRaii(this);
2601 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2602 } else {
2603 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2604 }
2605 }
2606 }
2607 if (result.isValid())
2608 RegisterTemporary(result);
2609 if (indent) {
2610 if (error)
2611 *error = kProcessing;
2612 return 0;
2613 }
2614 if (error) {
2615 switch (compRes) {
2616 case cling::Interpreter::kSuccess: *error = kNoError; break;
2617 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2618 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2619 }
2620 }
2621 if (compRes == cling::Interpreter::kSuccess
2622 && result.isValid()
2623 && !result.isVoid())
2624 {
2625 return result.simplisticCastAs<Longptr_t>();
2626 }
2627 return 0;
2628}
2629
2630////////////////////////////////////////////////////////////////////////////////
2631/// No-op; see TRint instead.
2632
2634{
2635}
2636
2637////////////////////////////////////////////////////////////////////////////////
2638/// \brief Add a directory to the list of directories in which the
2639/// interpreter looks for include files.
2640/// \param[in] path The path to the directory.
2641/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2642/// \b NOT supported.
2643/// \warning Only the path to the directory should be specified, without
2644/// prepending the \c -I prefix, i.e.
2645/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2646/// \c -I prefix is used it will be ignored.
2647void TCling::AddIncludePath(const char *path)
2648{
2650 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2651 // gCling->AddIncludePath() does not! Work around that inconsistency:
2652 if (path[0] == '-' && path[1] == 'I')
2653 path += 2;
2654 TString sPath(path);
2655 gSystem->ExpandPathName(sPath);
2656 fInterpreter->AddIncludePath(sPath.Data());
2657}
2658
2659////////////////////////////////////////////////////////////////////////////////
2660/// Visit all members over members, recursing over base classes.
2661
2662void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2663 const TClass* cl, Bool_t isTransient)
2664{
2668 }
2669
2670 if (!cl || cl->GetCollectionProxy()) {
2671 // We do not need to investigate the content of the STL
2672 // collection, they are opaque to us (and details are
2673 // uninteresting).
2674 return;
2675 }
2676
2677 static const TClassRef clRefString("std::string");
2678 if (clRefString == cl) {
2679 // We stream std::string without going through members..
2680 return;
2681 }
2682
2683 if (TClassEdit::IsStdArray(cl->GetName())) {
2684 // We treat std arrays as C arrays
2685 return;
2686 }
2687
2688 const char* cobj = (const char*) obj; // for ptr arithmetics
2689
2690 // Treat the case of std::complex in a special manner. We want to enforce
2691 // the layout of a stl implementation independent class, which is the
2692 // complex as implemented in ROOT5.
2693
2694 // A simple lambda to simplify the code
2695 auto inspInspect = [&] (ptrdiff_t offset){
2696 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2697 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2698 };
2699
2700 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2701 switch(complexType) {
2703 {
2704 break;
2705 }
2707 {
2708 inspInspect(sizeof(float));
2709 return;
2710 }
2712 {
2713 inspInspect(sizeof(double));
2714 return;
2715 }
2717 {
2718 inspInspect(sizeof(int));
2719 return;
2720 }
2722 {
2723 inspInspect(sizeof(long));
2724 return;
2725 }
2726 }
2727
2728 static clang::PrintingPolicy
2729 printPol(fInterpreter->getCI()->getLangOpts());
2730 if (printPol.Indentation) {
2731 // not yet initialized
2732 printPol.Indentation = 0;
2733 printPol.SuppressInitializers = true;
2734 }
2735
2736 const char* clname = cl->GetName();
2737 // Printf("Inspecting class %s\n", clname);
2738
2739 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2740 const clang::Decl *scopeDecl = 0;
2741 const clang::Type *recordType = 0;
2742
2743 if (cl->GetClassInfo()) {
2744 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2745 scopeDecl = clingCI->GetDecl();
2746 recordType = clingCI->GetType();
2747 } else {
2748 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2749 // Diags will complain about private classes:
2750 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2751 &recordType);
2752 }
2753 if (!scopeDecl) {
2754 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2755 return;
2756 }
2757 const clang::CXXRecordDecl* recordDecl
2758 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2759 if (!recordDecl) {
2760 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2761 return;
2762 }
2763
2764 {
2765 // Force possible deserializations first. We need to have no pending
2766 // Transaction when passing control flow to the inspector below (ROOT-7779).
2767 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2768
2769 astContext.getASTRecordLayout(recordDecl);
2770
2771 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2772 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2773 }
2774
2775 const clang::ASTRecordLayout& recLayout
2776 = astContext.getASTRecordLayout(recordDecl);
2777
2778 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2779 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2780 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2781 // cl->GetName());
2782 // }
2783 if (cl->Size() != recLayout.getSize().getQuantity()) {
2784 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2785 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2786 }
2787
2788 unsigned iNField = 0;
2789 // iterate over fields
2790 // FieldDecls are non-static, else it would be a VarDecl.
2791 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2792 eField = recordDecl->field_end(); iField != eField;
2793 ++iField, ++iNField) {
2794
2795
2796 clang::QualType memberQT = iField->getType();
2797 if (recordType) {
2798 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2799 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2800 }
2801 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2802 if (memberQT.isNull()) {
2803 std::string memberName;
2804 llvm::raw_string_ostream stream(memberName);
2805 // Don't trigger fopen of the source file to count lines:
2806 printPol.AnonymousTagLocations = false;
2807 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2808 stream.flush();
2809 Error("InspectMembers",
2810 "Cannot retrieve QualType for member %s while inspecting class %s",
2811 memberName.c_str(), clname);
2812 continue; // skip member
2813 }
2814 const clang::Type* memType = memberQT.getTypePtr();
2815 if (!memType) {
2816 std::string memberName;
2817 llvm::raw_string_ostream stream(memberName);
2818 // Don't trigger fopen of the source file to count lines:
2819 printPol.AnonymousTagLocations = false;
2820 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2821 stream.flush();
2822 Error("InspectMembers",
2823 "Cannot retrieve Type for member %s while inspecting class %s",
2824 memberName.c_str(), clname);
2825 continue; // skip member
2826 }
2827
2828 const clang::Type* memNonPtrType = memType;
2829 Bool_t ispointer = false;
2830 if (memNonPtrType->isPointerType()) {
2831 ispointer = true;
2832 clang::QualType ptrQT
2833 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2834 if (recordType) {
2835 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2836 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2837 }
2838 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2839 if (ptrQT.isNull()) {
2840 std::string memberName;
2841 llvm::raw_string_ostream stream(memberName);
2842 // Don't trigger fopen of the source file to count lines:
2843 printPol.AnonymousTagLocations = false;
2844 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2845 stream.flush();
2846 Error("InspectMembers",
2847 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2848 memberName.c_str(), clname);
2849 continue; // skip member
2850 }
2851 memNonPtrType = ptrQT.getTypePtr();
2852 }
2853
2854 // assemble array size(s): "[12][4][]"
2855 llvm::SmallString<8> arraySize;
2856 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2857 unsigned arrLevel = 0;
2858 bool haveErrorDueToArray = false;
2859 while (arrType) {
2860 ++arrLevel;
2861 arraySize += '[';
2862 const clang::ConstantArrayType* constArrType =
2863 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2864 if (constArrType) {
2865 constArrType->getSize().toStringUnsigned(arraySize);
2866 }
2867 arraySize += ']';
2868 clang::QualType subArrQT = arrType->getElementType();
2869 if (subArrQT.isNull()) {
2870 std::string memberName;
2871 llvm::raw_string_ostream stream(memberName);
2872 // Don't trigger fopen of the source file to count lines:
2873 printPol.AnonymousTagLocations = false;
2874 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2875 stream.flush();
2876 Error("InspectMembers",
2877 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2878 arrLevel, subArrQT.getAsString(printPol).c_str(),
2879 memberName.c_str(), clname);
2880 haveErrorDueToArray = true;
2881 break;
2882 }
2883 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2884 }
2885 if (haveErrorDueToArray) {
2886 continue; // skip member
2887 }
2888
2889 // construct member name
2890 std::string fieldName;
2891 if (memType->isPointerType()) {
2892 fieldName = "*";
2893 }
2894
2895 // Check if this field has a custom ioname, if not, just use the one of the decl
2896 std::string ioname(iField->getName());
2897 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2898 fieldName += ioname;
2899 fieldName += arraySize;
2900
2901 // get member offset
2902 // NOTE currently we do not support bitfield and do not support
2903 // member that are not aligned on 'bit' boundaries.
2904 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2905 ptrdiff_t fieldOffset = offset.getQuantity();
2906
2907 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2908 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2909 // R__insp.InspectMember(fName, "fName.");
2910 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2911
2912 // If the class has a custom streamer and the type of the filed is a
2913 // private enum, struct or class, skip it.
2914 if (!insp.IsTreatingNonAccessibleTypes()){
2915 auto iFiledQtype = iField->getType();
2916 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2917 auto declAccess = tagDecl->getAccess();
2918 if (declAccess == AS_private || declAccess == AS_protected) {
2919 continue;
2920 }
2921 }
2922 }
2923
2924 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2925
2926 if (!ispointer) {
2927 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2928 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2929 // nested objects get an extra call to InspectMember
2930 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2931 std::string sFieldRecName;
2932 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2934 clang::QualType(memNonPtrType,0),
2935 *fInterpreter,
2937 }
2938
2939 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2940 // if we can not find the member (which should not really happen),
2941 // let's consider it transient.
2942 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2943
2944 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2945 (fieldName + '.').c_str(), transient);
2946
2947 }
2948 }
2949 } // loop over fields
2950
2951 // inspect bases
2952 // TNamed::ShowMembers(R__insp);
2953 unsigned iNBase = 0;
2954 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2955 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2956 iBase != eBase; ++iBase, ++iNBase) {
2957 clang::QualType baseQT = iBase->getType();
2958 if (baseQT.isNull()) {
2959 Error("InspectMembers",
2960 "Cannot find QualType for base number %d while inspecting class %s",
2961 iNBase, clname);
2962 continue;
2963 }
2964 const clang::CXXRecordDecl* baseDecl
2965 = baseQT->getAsCXXRecordDecl();
2966 if (!baseDecl) {
2967 Error("InspectMembers",
2968 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2969 iNBase, clname);
2970 continue;
2971 }
2972 TClass* baseCl=nullptr;
2973 std::string sBaseName;
2974 // Try with the DeclId
2975 std::vector<TClass*> foundClasses;
2976 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2977 if (foundClasses.size()==1){
2978 baseCl=foundClasses[0];
2979 } else {
2980 // Try with the normalised Name, as a fallback
2981 if (!baseCl){
2983 baseQT,
2984 *fInterpreter,
2986 baseCl = TClass::GetClass(sBaseName.c_str());
2987 }
2988 }
2989
2990 if (!baseCl){
2991 std::string qualNameForDiag;
2992 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2993 Error("InspectMembers",
2994 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2995 continue;
2996 }
2997
2998 int64_t baseOffset;
2999 if (iBase->isVirtual()) {
3001 if (!isTransient) {
3002 Error("InspectMembers",
3003 "Base %s of class %s is virtual but no object provided",
3004 sBaseName.c_str(), clname);
3005 }
3007 } else {
3008 // We have an object to determine the vbase offset.
3010 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3011 if (ci && baseCi) {
3012 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3013 true /*isDerivedObj*/);
3014 if (baseOffset == -1) {
3015 Error("InspectMembers",
3016 "Error calculating offset of virtual base %s of class %s",
3017 sBaseName.c_str(), clname);
3018 }
3019 } else {
3020 Error("InspectMembers",
3021 "Cannot calculate offset of virtual base %s of class %s",
3022 sBaseName.c_str(), clname);
3023 continue;
3024 }
3025 }
3026 } else {
3027 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3028 }
3029 // TOFIX: baseCl can be null here!
3030 if (baseCl->IsLoaded()) {
3031 // For loaded class, CallShowMember will (especially for TObject)
3032 // call the virtual ShowMember rather than the class specific version
3033 // resulting in an infinite recursion.
3034 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3035 } else {
3036 baseCl->CallShowMembers(cobj + baseOffset,
3037 insp, isTransient);
3038 }
3039 } // loop over bases
3040}
3041
3042////////////////////////////////////////////////////////////////////////////////
3043/// Reset the interpreter internal state in case a previous action was not correctly
3044/// terminated.
3045
3047{
3048 // No-op there is not equivalent state (to be cleared) in Cling.
3049}
3050
3051////////////////////////////////////////////////////////////////////////////////
3052/// Delete existing temporary values.
3053
3055{
3056 // No-op for cling due to cling::Value.
3057}
3058
3059////////////////////////////////////////////////////////////////////////////////
3060/// Declare code to the interpreter, without any of the interpreter actions
3061/// that could trigger a re-interpretation of the code. I.e. make cling
3062/// behave like a compiler: no dynamic lookup, no input wrapping for
3063/// subsequent execution, no automatic provision of declarations but just a
3064/// plain #include.
3065/// Returns true on success, false on failure.
3066
3067bool TCling::Declare(const char* code)
3068{
3070
3071 SuspendAutoLoadingRAII autoLoadOff(this);
3072 SuspendAutoParsing autoParseRaii(this);
3073
3074 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3075 fInterpreter->enableDynamicLookup(false);
3076 bool oldRawInput = fInterpreter->isRawInputEnabled();
3077 fInterpreter->enableRawInput(true);
3078
3079 Bool_t ret = LoadText(code);
3080
3081 fInterpreter->enableRawInput(oldRawInput);
3082 fInterpreter->enableDynamicLookup(oldDynLookup);
3083 return ret;
3084}
3085
3086////////////////////////////////////////////////////////////////////////////////
3087/// It calls a "fantom" method to synchronize user keyboard input
3088/// and ROOT prompt line.
3089
3091{
3093}
3094
3095// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3096// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3097// was already taking a lock.
3098static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3099{
3100 // Check shared library.
3101 TString tLibName(libname);
3102 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3103 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3104 return false;
3105}
3106
3107Bool_t TCling::IsLibraryLoaded(const char* libname) const
3108{
3110 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3111}
3112
3113////////////////////////////////////////////////////////////////////////////////
3114/// Return true if ROOT has cxxmodules pcm for a given library name.
3115// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3116Bool_t TCling::HasPCMForLibrary(const char *libname) const
3117{
3118 llvm::StringRef ModuleName(libname);
3119 ModuleName = llvm::sys::path::stem(ModuleName);
3120 ModuleName.consume_front("lib");
3121
3122 // FIXME: In case when the modulemap is not yet loaded we will return the
3123 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3124 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3125 // which may happen after calling this interface. Maybe we should also check
3126 // if there is a Event.pcm file and a module.modulemap, load it and return
3127 // true.
3128 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3129 clang::Module *M = moduleMap.findModule(ModuleName);
3130 return M && !M->IsMissingRequirement && M->getASTFile();
3131}
3132
3133////////////////////////////////////////////////////////////////////////////////
3134/// Return true if the file has already been loaded by cint.
3135/// We will try in this order:
3136/// actual filename
3137/// filename as a path relative to
3138/// the include path
3139/// the shared library path
3140
3141Bool_t TCling::IsLoaded(const char* filename) const
3142{
3144
3145 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3146 // cling::DynamicLibraryManager.
3147
3148 std::string file_name = filename;
3149 size_t at = std::string::npos;
3150 while ((at = file_name.find("/./")) != std::string::npos)
3151 file_name.replace(at, 3, "/");
3152
3153 std::string filesStr = "";
3154 llvm::raw_string_ostream filesOS(filesStr);
3155 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3156 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3157 filesOS.flush();
3158
3159 llvm::SmallVector<llvm::StringRef, 100> files;
3160 llvm::StringRef(filesStr).split(files, "\n");
3161
3162 std::set<std::string> fileMap;
3163 // Fill fileMap; return early on exact match.
3164 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3165 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3166 if ((*iF) == file_name.c_str()) return kTRUE; // exact match
3167 fileMap.insert(*iF);
3168 }
3169
3170 if (fileMap.empty()) return kFALSE;
3171
3172 // Check MacroPath.
3173 TString sFilename(file_name.c_str());
3175 && fileMap.count(sFilename.Data())) {
3176 return kTRUE;
3177 }
3178
3179 // Check IncludePath.
3180 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3181 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3182 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3183 while (incPath.Index(" :") != -1) {
3184 incPath.ReplaceAll(" :", ":");
3185 }
3186 incPath.Prepend(".:");
3187 sFilename = file_name.c_str();
3188 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3189 && fileMap.count(sFilename.Data())) {
3190 return kTRUE;
3191 }
3192
3193 // Check shared library.
3194 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3195 return kTRUE;
3196
3197 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3198 const clang::DirectoryLookup *CurDir = 0;
3199 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3200 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3201 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
3202 clang::SourceLocation(),
3203 /*isAngled*/ false,
3204 /*FromDir*/ 0, CurDir,
3205 clang::ArrayRef<std::pair<const clang::FileEntry *,
3206 const clang::DirectoryEntry *>>(),
3207 /*SearchPath*/ 0,
3208 /*RelativePath*/ 0,
3209 /*RequestingModule*/ 0,
3210 /*SuggestedModule*/ 0,
3211 /*IsMapped*/ 0,
3212 /*IsFrameworkFound*/ nullptr,
3213 /*SkipCache*/ false,
3214 /*BuildSystemModule*/ false,
3215 /*OpenFile*/ false,
3216 /*CacheFail*/ false);
3217 if (FE && FE->isValid()) {
3218 // check in the source manager if the file is actually loaded
3219 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3220 // this works only with header (and source) files...
3221 clang::FileID FID = SM.translateFile(FE);
3222 if (!FID.isInvalid() && FID.getHashValue() == 0)
3223 return kFALSE;
3224 else {
3225 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3226 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
3227 return kFALSE;
3228 if (!FID.isInvalid())
3229 return kTRUE;
3230 }
3231 // ...then check shared library again, but with full path now
3232 sFilename = FE->getName();
3233 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3234 && fileMap.count(sFilename.Data())) {
3235 return kTRUE;
3236 }
3237 }
3238 return kFALSE;
3239}
3240
3241
3242#if defined(R__MACOSX)
3243
3244////////////////////////////////////////////////////////////////////////////////
3245/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3246/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3247/// to `-lFOO` such that it can be passed to the linker.
3248/// This is a unique feature of macOS 11.
3249
3250static bool R__UpdateLibFileForLinking(TString &lib)
3251{
3252 const char *mapfile = nullptr;
3253#if __x86_64__
3254 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3255#elif __arm64__
3256 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3257#else
3258 #error unsupported architecture
3259#endif
3260 if (std::ifstream cacheMap{mapfile}) {
3261 std::string line;
3262 while (getline(cacheMap, line)) {
3263 if (line.find(lib) != std::string::npos) {
3264 lib.ReplaceAll("/usr/lib/lib","-l");
3265 lib.ReplaceAll(".dylib","");
3266 return true;
3267 }
3268 }
3269 return false;
3270 }
3271 return false;
3272}
3273#endif // R__MACOSX
3274
3275#ifdef R__LINUX
3276
3277////////////////////////////////////////////////////////////////////////////////
3278/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3279/// Collects opened libraries.
3280
3281static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3282{
3283 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3284 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3285
3286 auto newLibs = static_cast<std::vector<std::string>*>(data);
3287 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3288 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3289 if (info->dlpi_name && info->dlpi_name[0]
3290 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3291 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3292 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3293 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3294 newLibs->emplace_back(info->dlpi_name);
3295 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3296 }
3297 // No matter what the doc says, return != 0 means "stop the iteration".
3298 return 0;
3299}
3300
3301#endif // R__LINUX
3302
3303
3304////////////////////////////////////////////////////////////////////////////////
3305
3307{
3308#if defined(R__WIN32) || defined(__CYGWIN__)
3309 HMODULE hModules[1024];
3310 void *hProcess;
3311 unsigned long cbModules;
3312 unsigned int i;
3313 hProcess = (void *)::GetCurrentProcess();
3314 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3315 // start at 1 to skip the executable itself
3316 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3317 static const int bufsize = 260;
3318 wchar_t winname[bufsize];
3319 char posixname[bufsize];
3320 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3321#if defined(__CYGWIN__)
3322 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3323#else
3324 std::wstring wpath = winname;
3325 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3326 string path(wpath.begin(), wpath.end());
3327 strncpy(posixname, path.c_str(), bufsize);
3328#endif
3329 if (!fSharedLibs.Contains(posixname)) {
3330 RegisterLoadedSharedLibrary(posixname);
3331 }
3332 }
3333#elif defined(R__MACOSX)
3334 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3335 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3336
3337 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3338 // Skip non-dylibs
3339 if (mh->filetype == MH_DYLIB) {
3340 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3341 RegisterLoadedSharedLibrary(imageName);
3342 }
3343 }
3344
3345 ++imageIndex;
3346 }
3347 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3348#elif defined(R__LINUX)
3349 // fPrevLoadedDynLibInfo is unused on Linux.
3351
3352 std::vector<std::string> newLibs;
3353 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3354 for (auto &&lib: newLibs)
3355 RegisterLoadedSharedLibrary(lib.c_str());
3356#else
3357 Error("TCling::UpdateListOfLoadedSharedLibraries",
3358 "Platform not supported!");
3359#endif
3360}
3361
3362namespace {
3363template <int N>
3364static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3365 return !strncmp(haystack, needle, N - 1);
3366}
3367}
3368
3369////////////////////////////////////////////////////////////////////////////////
3370/// Register a new shared library name with the interpreter; add it to
3371/// fSharedLibs.
3372
3373void TCling::RegisterLoadedSharedLibrary(const char* filename)
3374{
3375 // Ignore NULL filenames, aka "the process".
3376 if (!filename) return;
3377
3378 // Tell the interpreter that this library is available; all libraries can be
3379 // used to resolve symbols.
3380 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3381 if (!DLM->isLibraryLoaded(filename)) {
3382 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3383 }
3384
3385#if defined(R__MACOSX)
3386 // Check that this is not a system library that does not exist on disk.
3387 auto lenFilename = strlen(filename);
3388 auto isInMacOSSystemDir = [](const char *fn) {
3389 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3390 };
3391 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3392
3393 // These we should not link with (e.g. because they forward to .tbd):
3394 || StartsWithStrLit(filename, "/usr/lib/system/")
3395 || StartsWithStrLit(filename, "/usr/lib/libc++")
3396 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3397 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3398 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3399 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3400 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3401 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3402 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3403 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3404 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3405 || StartsWithStrLit(filename, "/usr/lib/libauto")
3406 || StartsWithStrLit(filename, "/usr/lib/libcups")
3407 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3408 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3409 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3410 || StartsWithStrLit(filename, "/usr/lib/libpam")
3411 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3412 || StartsWithStrLit(filename, "/usr/lib/libextension")
3413 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3414 || StartsWithStrLit(filename, "/usr/lib/liboah")
3415 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3416 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3417 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3418 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3419
3420 // The system lib is likely in macOS's blob.
3421 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3422
3423 // "Link against the umbrella framework 'System.framework' instead"
3424 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3425 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3426 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3427
3428 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3429 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3430 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3431 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3432 return;
3433 TString sFileName(filename);
3434 R__UpdateLibFileForLinking(sFileName);
3435 filename = sFileName.Data();
3436#elif defined(__CYGWIN__)
3437 // Check that this is not a system library
3438 static const int bufsize = 260;
3439 char posixwindir[bufsize];
3440 char *windir = getenv("WINDIR");
3441 if (windir)
3442 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3443 else
3444 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3445 if (strstr(filename, posixwindir) ||
3446 strstr(filename, "/usr/bin/cyg"))
3447 return;
3448#elif defined(R__WIN32)
3449 if (strstr(filename, "/Windows/"))
3450 return;
3451#elif defined (R__LINUX)
3452 if (strstr(filename, "/ld-linux")
3453 || strstr(filename, "linux-gnu/")
3454 || strstr(filename, "/libstdc++.")
3455 || strstr(filename, "/libgcc")
3456 || strstr(filename, "/libc.")
3457 || strstr(filename, "/libdl.")
3458 || strstr(filename, "/libm."))
3459 return;
3460#endif
3461 // Update string of available libraries.
3462 if (!fSharedLibs.IsNull()) {
3463 fSharedLibs.Append(" ");
3464 }
3465 fSharedLibs.Append(filename);
3466}
3467
3468////////////////////////////////////////////////////////////////////////////////
3469/// Load a library file in cling's memory.
3470/// if 'system' is true, the library is never unloaded.
3471/// Return 0 on success, -1 on failure.
3472
3473Int_t TCling::Load(const char* filename, Bool_t system)
3474{
3475 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3476
3477 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3479 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3480 std::string canonLib = DLM->lookupLibrary(filename);
3481 cling::DynamicLibraryManager::LoadLibResult res
3482 = cling::DynamicLibraryManager::kLoadLibNotFound;
3483 if (!canonLib.empty()) {
3484 if (system)
3485 res = DLM->loadLibrary(filename, system, true);
3486 else {
3487 // For the non system libs, we'd like to be able to unload them.
3488 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3489 cling::Interpreter::CompilationResult compRes;
3490 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3491 if (compRes == cling::Interpreter::kSuccess)
3492 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3493 }
3494 }
3495
3496 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3498 }
3499 switch (res) {
3500 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3501 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3502 default: break;
3503 };
3504 return -1;
3505}
3506
3507////////////////////////////////////////////////////////////////////////////////
3508/// Load a macro file in cling's memory.
3509
3510void TCling::LoadMacro(const char* filename, EErrorCode* error)
3511{
3512 ProcessLine(Form(".L %s", filename), error);
3513}
3514
3515////////////////////////////////////////////////////////////////////////////////
3516/// Let cling process a command line asynch.
3517
3519{
3520 return ProcessLine(line, error);
3521}
3522
3523////////////////////////////////////////////////////////////////////////////////
3524/// Let cling process a command line synchronously, i.e we are waiting
3525/// it will be finished.
3526
3528{
3530 if (gApplication) {
3531 if (gApplication->IsCmdThread()) {
3532 return ProcessLine(line, error);
3533 }
3534 return 0;
3535 }
3536 return ProcessLine(line, error);
3537}
3538
3539////////////////////////////////////////////////////////////////////////////////
3540/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3541/// however not declarations, like "Int_t x;").
3542
3544{
3545#ifdef R__WIN32
3546 // Test on ApplicationImp not being 0 is needed because only at end of
3547 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3548 // we can not use it.
3550 while (gROOT->IsLineProcessing() && !gApplication) {
3551 Warning("Calc", "waiting for cling thread to free");
3552 gSystem->Sleep(500);
3553 }
3554 gROOT->SetLineIsProcessing();
3555 }
3556#endif // R__WIN32
3558 if (error) {
3559 *error = TInterpreter::kNoError;
3560 }
3561 cling::Value valRef;
3562 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3563 try {
3564 cr = fInterpreter->evaluate(line, valRef);
3565 }
3566 catch (cling::InterpreterException& ex)
3567 {
3568 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3569 ex.diagnose();
3570 cr = cling::Interpreter::kFailure;
3571 }
3572
3573 if (cr != cling::Interpreter::kSuccess) {
3574 // Failure in compilation.
3575 if (error) {
3576 // Note: Yes these codes are weird.
3578 }
3579 return 0L;
3580 }
3581 if (!valRef.isValid()) {
3582 // Failure at runtime.
3583 if (error) {
3584 // Note: Yes these codes are weird.
3585 *error = TInterpreter::kDangerous;
3586 }
3587 return 0L;
3588 }
3589
3590 if (valRef.isVoid()) {
3591 return 0;
3592 }
3593
3594 RegisterTemporary(valRef);
3595#ifdef R__WIN32
3597 gROOT->SetLineHasBeenProcessed();
3598 }
3599#endif // R__WIN32
3600 return valRef.simplisticCastAs<Longptr_t>();
3601}
3602
3603////////////////////////////////////////////////////////////////////////////////
3604/// Set a getline function to call when input is needed.
3605
3606void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3607 void (*histaddFunc)(const char* line))
3608{
3609 // If cling offers a replacement for G__pause(), it would need to
3610 // also offer a way to customize at least the history recording.
3611
3612#if defined(R__MUST_REVISIT)
3613#if R__MUST_REVISIT(6,2)
3614 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3615#endif
3616#endif
3617}
3618
3619////////////////////////////////////////////////////////////////////////////////
3620/// Helper function to increase the internal Cling count of transactions
3621/// that change the AST.
3622
3623Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3624{
3626
3627 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3628 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3629 || T.macros_begin() != T.macros_end()
3630 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3632 return true;
3633 }
3634 return false;
3635}
3636
3637////////////////////////////////////////////////////////////////////////////////
3638/// Delete object from cling symbol table so it can not be used anymore.
3639/// cling objects are always on the heap.
3640
3642{
3643 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3644 // put in place the Read/Write part here. Keeping the write lock
3645 // here is 'catasptrophic' for scaling as it means that ALL calls
3646 // to RecursiveRemove will take the write lock and performance
3647 // of many threads trying to access the write lock at the same
3648 // time is relatively bad.
3650 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3651 // (but isn't at the moment).
3652 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3653 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3654 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3656 DeleteGlobal(obj);
3657 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3658 }
3659 }
3660}
3661
3662////////////////////////////////////////////////////////////////////////////////
3663/// Pressing Ctrl+C should forward here. In the case where we have had
3664/// continuation requested we must reset it.
3665
3667{
3668 fMetaProcessor->cancelContinuation();
3669 // Reset the Cling state to the state saved by the last call to
3670 // TCling::SaveContext().
3671#if defined(R__MUST_REVISIT)
3672#if R__MUST_REVISIT(6,2)
3674 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3675#endif
3676#endif
3677}
3678
3679////////////////////////////////////////////////////////////////////////////////
3680/// Reset the Cling state to its initial state.
3681
3683{
3684#if defined(R__MUST_REVISIT)
3685#if R__MUST_REVISIT(6,2)
3687 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3688#endif
3689#endif
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Reset in Cling the list of global variables to the state saved by the last
3694/// call to TCling::SaveGlobalsContext().
3695///
3696/// Note: Right now, all we do is run the global destructors.
3697
3699{
3701 // TODO:
3702 // Here we should iterate over the transactions (N-3) and revert.
3703 // N-3 because the first three internal to cling.
3704
3705 fInterpreter->runAndRemoveStaticDestructors();
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3710/// call to TCling::SaveGlobalsContext().
3711
3713{
3714#if defined(R__MUST_REVISIT)
3715#if R__MUST_REVISIT(6,2)
3717 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3718#endif
3719#endif
3720}
3721
3722////////////////////////////////////////////////////////////////////////////////
3723/// Rewind Cling dictionary to the point where it was before executing
3724/// the current macro. This function is typically called after SEGV or
3725/// ctlr-C after doing a longjmp back to the prompt.
3726
3728{
3729#if defined(R__MUST_REVISIT)
3730#if R__MUST_REVISIT(6,2)
3732 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3733#endif
3734#endif
3735}
3736
3737////////////////////////////////////////////////////////////////////////////////
3738/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3739/// Returns 1 in case of success and 0 in case object was not in table.
3740
3742{
3743#if defined(R__MUST_REVISIT)
3744#if R__MUST_REVISIT(6,2)
3746 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3747#endif
3748#endif
3749 return 0;
3750}
3751
3752////////////////////////////////////////////////////////////////////////////////
3753/// Undeclare obj called name.
3754/// Returns 1 in case of success, 0 for failure.
3755
3757{
3758#if defined(R__MUST_REVISIT)
3759#if R__MUST_REVISIT(6,2)
3760 Warning("DeleteVariable","should do more that just reseting the value to zero");
3761#endif
3762#endif
3763
3765 llvm::StringRef srName(name);
3766 const char* unscopedName = name;
3767 llvm::StringRef::size_type posScope = srName.rfind("::");
3768 const clang::DeclContext* declCtx = 0;
3769 if (posScope != llvm::StringRef::npos) {
3770 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3771 const clang::Decl* scopeDecl
3772 = lh.findScope(srName.substr(0, posScope),
3773 cling::LookupHelper::WithDiagnostics);
3774 if (!scopeDecl) {
3775 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3776 name);
3777 return 0;
3778 }
3779 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3780 if (!declCtx) {
3781 Error("DeleteVariable",
3782 "Enclosing scope for variable %s is not a declaration context",
3783 name);
3784 return 0;
3785 }
3786 unscopedName += posScope + 2;
3787 }
3788 // Could trigger deserialization of decls.
3789 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3790 clang::NamedDecl* nVarDecl
3791 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3792 if (!nVarDecl) {
3793 Error("DeleteVariable", "Unknown variable %s", name);
3794 return 0;
3795 }
3796 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3797 if (!varDecl) {
3798 Error("DeleteVariable", "Entity %s is not a variable", name);
3799 return 0;
3800 }
3801
3802 clang::QualType qType = varDecl->getType();
3803 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3804 // Cannot set a reference's address to nullptr; the JIT can place it
3805 // into read-only memory (ROOT-7100).
3806 if (type->isPointerType()) {
3807 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3808 // set pointer to invalid.
3809 if (ppInt) *ppInt = 0;
3810 }
3811 return 1;
3812}
3813
3814////////////////////////////////////////////////////////////////////////////////
3815/// Save the current Cling state.
3816
3818{
3819#if defined(R__MUST_REVISIT)
3820#if R__MUST_REVISIT(6,2)
3822 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3823#endif
3824#endif
3825}
3826
3827////////////////////////////////////////////////////////////////////////////////
3828/// Save the current Cling state of global objects.
3829
3831{
3832#if defined(R__MUST_REVISIT)
3833#if R__MUST_REVISIT(6,2)
3835 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3836#endif
3837#endif
3838}
3839
3840////////////////////////////////////////////////////////////////////////////////
3841/// No op: see TClingCallbacks (used to update the list of globals)
3842
3844{
3845}
3846
3847////////////////////////////////////////////////////////////////////////////////
3848/// No op: see TClingCallbacks (used to update the list of global functions)
3849
3851{
3852}
3853
3854////////////////////////////////////////////////////////////////////////////////
3855/// No op: see TClingCallbacks (used to update the list of types)
3856
3858{
3859}
3860
3861////////////////////////////////////////////////////////////////////////////////
3862/// Check in what order the member of a tuple are layout.
3863enum class ETupleOrdering {
3864 kAscending,
3867};
3868
3870{
3873};
3874
3876{
3879};
3880
3882{
3883 std::tuple<int,double> value;
3886
3887 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3888 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3889
3890 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3891 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3892
3893 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3894 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3895
3896 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3898 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3900 } else {
3902 }
3903}
3904
3905static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3906{
3907 TClassEdit::TSplitType tupleContent(classname);
3908 std::string alternateName = "TEmulatedTuple";
3909 alternateName.append( classname + 5 );
3910
3911 std::string fullname = "ROOT::Internal::" + alternateName;
3912 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3913 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3914 return fullname;
3915
3916 std::string guard_name;
3917 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3918 std::ostringstream guard;
3919 guard << "ROOT_INTERNAL_TEmulated_";
3920 guard << guard_name;
3921
3922 std::ostringstream alternateTuple;
3923 alternateTuple << "#ifndef " << guard.str() << "\n";
3924 alternateTuple << "#define " << guard.str() << "\n";
3925 alternateTuple << "namespace ROOT { namespace Internal {\n";
3926 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3927 alternateTuple << "template <> struct " << alternateName << " {\n";
3928
3929 // This could also be a compile time choice ...
3930 switch(IsTupleAscending()) {
3932 unsigned int nMember = 0;
3933 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3934 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3935 while (iter != theEnd) {
3936 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3937 ++iter;
3938 ++nMember;
3939 }
3940 break;
3941 }
3943 unsigned int nMember = tupleContent.fElements.size() - 3;
3944 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3945 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3946 while (iter != theEnd) {
3947 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3948 ++iter;
3949 --nMember;
3950 }
3951 break;
3952 }
3954 Fatal("TCling::SetClassInfo::AlternateTuple",
3955 "Layout of std::tuple on this platform is unexpected.");
3956 break;
3957 }
3958 }
3959
3960 alternateTuple << "};\n";
3961 alternateTuple << "}}\n";
3962 alternateTuple << "#endif\n";
3963 if (!gCling->Declare(alternateTuple.str().c_str())) {
3964 Error("Load","Could not declare %s",alternateName.c_str());
3965 return "";
3966 }
3967 alternateName = "ROOT::Internal::" + alternateName;
3968 return alternateName;
3969}
3970
3971////////////////////////////////////////////////////////////////////////////////
3972/// Set pointer to the TClingClassInfo in TClass.
3973/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3974/// already have one.
3975
3977{
3978 // We are shutting down, there is no point in reloading, it only triggers
3979 // redundant deserializations.
3980 if (fIsShuttingDown) {
3981 // Remove the decl_id from the DeclIdToTClass map
3982 if (cl->fClassInfo) {
3984 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3985 // Test again as another thread may have set fClassInfo to nullptr.
3986 if (TClinginfo) {
3987 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3988 }
3989 delete TClinginfo;
3990 cl->fClassInfo = nullptr;
3991 }
3992 return;
3993 }
3994
3996 if (cl->fClassInfo && !reload) {
3997 return;
3998 }
3999 //Remove the decl_id from the DeclIdToTClass map
4000 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4001 if (TClinginfo) {
4002 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4003 }
4004 delete TClinginfo;
4005 cl->fClassInfo = 0;
4006 std::string name(cl->GetName());
4007
4008 // Handle the special case of 'tuple' where we ignore the real implementation
4009 // details and just overlay a 'simpler'/'simplistic' version that is easy
4010 // for the I/O to understand and handle.
4011 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4012
4013 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
4014
4015 }
4016
4017 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4018 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4019 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4020 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4021 // TClingClassInfoReadOnly.
4022 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4023 if (!info->IsValid()) {
4024 if (cl->fState != TClass::kHasTClassInit) {
4025 if (cl->fStreamerInfo->GetEntries() != 0) {
4027 } else {
4029 }
4030 }
4031 delete info;
4032 return;
4033 }
4034 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4035 // In case a class contains an external enum, the enum will be seen as a
4036 // class. We must detect this special case and make the class a Zombie.
4037 // Here we assume that a class has at least one method.
4038 // We can NOT call TClass::Property from here, because this method
4039 // assumes that the TClass is well formed to do a lot of information
4040 // caching. The method SetClassInfo (i.e. here) is usually called during
4041 // the building phase of the TClass, hence it is NOT well formed yet.
4042 Bool_t zombieCandidate = kFALSE;
4043 if (
4044 info->IsValid() &&
4045 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4046 ) {
4047 zombieCandidate = kTRUE;
4048 }
4049 if (!info->IsLoaded()) {
4050 if (info->Property() & (kIsNamespace)) {
4051 // Namespaces can have info but no corresponding CINT dictionary
4052 // because they are auto-created if one of their contained
4053 // classes has a dictionary.
4054 zombieCandidate = kTRUE;
4055 }
4056 // this happens when no dictionary is available
4057 delete info;
4058 cl->fClassInfo = 0;
4059 }
4060 if (zombieCandidate && !cl->GetCollectionType()) {
4061 cl->MakeZombie();
4062 }
4063 // If we reach here, the info was valid (See early returns).
4064 if (cl->fState != TClass::kHasTClassInit) {
4065 if (cl->fClassInfo) {
4068 } else {
4069// if (TClassEdit::IsSTLCont(cl->GetName()) {
4070// There will be an emulated collection proxy, is that the same?
4071// cl->fState = TClass::kEmulated;
4072// } else {
4073 if (cl->fStreamerInfo->GetEntries() != 0) {
4075 } else {
4077 }
4078// }
4079 }
4080 }
4081 if (cl->fClassInfo) {
4082 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4083 }
4084}
4085
4086////////////////////////////////////////////////////////////////////////////////
4087/// Checks if an entity with the specified name is defined in Cling.
4088/// Returns kUnknown if the entity is not defined.
4089/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4090/// Returns kKnown if the entity is defined.
4091///
4092/// By default, structs, namespaces, classes, enums and unions are looked for.
4093/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4094/// namespaces only are considered. I.e. if the name is an enum or a union,
4095/// the returned value is false.
4096///
4097/// In the case where the class is not loaded and belongs to a namespace
4098/// or is nested, looking for the full class name is outputting a lots of
4099/// (expected) error messages. Currently the only way to avoid this is to
4100/// specifically check that each level of nesting is already loaded.
4101/// In case of templates the idea is that everything between the outer
4102/// '<' and '>' has to be skipped, e.g.: aap<pippo<noot>::klaas>::a_class
4103
4105TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4106{
4108 static const char *anonEnum = "anonymous enum ";
4109 static const int cmplen = strlen(anonEnum);
4110
4111 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4112 return kUnknown;
4113 }
4114
4115 // Do not turn on the AutoLoading if it is globally off.
4116 autoload = autoload && IsClassAutoLoadingEnabled();
4117
4118 // Avoid the double search below in case the name is a fundamental type
4119 // or typedef to a fundamental type.
4120 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4121 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4122
4123 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4124 && fundType->GetType() > 0) {
4125 // Fundamental type, no a class.
4126 return kUnknown;
4127 }
4128
4129 // Migrated from within TClass::GetClass
4130 // If we want to know if a class or a namespace with this name exists in the
4131 // interpreter and this is an enum in the type system, before or after loading
4132 // according to the autoload function argument, return kUnknown.
4133 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4134 return kUnknown;
4135
4136 const char *classname = name;
4137
4138 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4139 class MaybeSuspendAutoLoadParse {
4140 int fStoreAutoLoad = 0;
4141 int fStoreAutoParse = 0;
4142 bool fSuspendedAutoParse = false;
4143 public:
4144 MaybeSuspendAutoLoadParse(int autoload) {
4145 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4146 }
4147
4148 void SuspendAutoParsing() {
4149 fSuspendedAutoParse = true;
4150 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4151 }
4152
4153 ~MaybeSuspendAutoLoadParse() {
4154 if (fSuspendedAutoParse)
4155 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4156 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4157 }
4158 };
4159
4160 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4161 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4162 autoLoadParseRAII.SuspendAutoParsing();
4163
4164 // First we want to check whether the decl exist, but _without_
4165 // generating any template instantiation. However, the lookup
4166 // still will create a forward declaration of the class template instance
4167 // if it exist. In this case, the return value of findScope will still
4168 // be zero but the type will be initialized.
4169 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4170 // this forward declaration.
4171 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4172 const clang::Type *type = 0;
4173 const clang::Decl *decl
4174 = lh.findScope(classname,
4175 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4176 : cling::LookupHelper::NoDiagnostics,
4177 &type, /* intantiateTemplate= */ false );
4178 if (!decl) {
4179 std::string buf = TClassEdit::InsertStd(classname);
4180 decl = lh.findScope(buf,
4181 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4182 : cling::LookupHelper::NoDiagnostics,
4183 &type,false);
4184 }
4185
4186 if (type) {
4187 // If decl==0 and the type is valid, then we have a forward declaration.
4188 if (!decl) {
4189 // If we have a forward declaration for a class template instantiation,
4190 // we want to ignore it if it was produced/induced by the call to
4191 // findScope, however we can not distinguish those from the
4192 // instantiation induce by 'soft' use (and thus also induce by the
4193 // same underlying code paths)
4194 // ['soft' use = use not requiring a complete definition]
4195 // So to reduce the amount of disruption to the existing code we
4196 // would just ignore those for STL collection, for which we really
4197 // need to have the compiled collection proxy (and thus the TClass
4198 // bootstrap).
4199 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4200 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4201 (type->getAsCXXRecordDecl());
4202 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4203 // Since the point of instantiation is invalid, we 'guess' that
4204 // the 'instantiation' of the forwarded type appended in
4205 // findscope.
4206 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4207 // For STL Collection we return kUnknown.
4208 return kUnknown;
4209 }
4210 }
4211 }
4213 if (!tci.IsValid()) {
4214 return kUnknown;
4215 }
4216 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4218
4219 if (tci.Property() & propertiesMask) {
4220 bool hasClassDefInline = false;
4221 if (isClassOrNamespaceOnly) {
4222 // We do not need to check for ClassDefInline when this is called from
4223 // TClass::Init, we only do it for the call from TClass::GetClass.
4224 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
4225 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
4226
4227 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4228 int lineNumber = 0;
4229 bool success = false;
4230 std::tie(success, lineNumber) =
4231 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4232 hasClassDefInline = success && (lineNumber == -1);
4233 }
4234 }
4235
4236 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4237 // , hasClassDefInline);
4238
4239 // We are now sure that the entry is not in fact an autoload entry.
4240 if (hasClassDefInline)
4241 return kWithClassDefInline;
4242 else
4243 return kKnown;
4244 } else {
4245 // We are now sure that the entry is not in fact an autoload entry.
4246 return kUnknown;
4247 }
4248 }
4249
4250 if (decl)
4251 return kKnown;
4252 else
4253 return kUnknown;
4254
4255 // Setting up iterator part of TClingTypedefInfo is too slow.
4256 // Copy the lookup code instead:
4257 /*
4258 TClingTypedefInfo t(fInterpreter, name);
4259 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4260 delete[] classname;
4261 return kTRUE;
4262 }
4263 */
4264
4265// const clang::Decl *decl = lh.findScope(name);
4266// if (!decl) {
4267// std::string buf = TClassEdit::InsertStd(name);
4268// decl = lh.findScope(buf);
4269// }
4270
4271// return (decl);
4272}
4273
4274////////////////////////////////////////////////////////////////////////////////
4275/// Return true if there is a class template by the given name ...
4276
4278{
4279 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4280 const clang::Decl *decl
4281 = lh.findClassTemplate(name,
4282 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4283 : cling::LookupHelper::NoDiagnostics);
4284 if (!decl) {
4285 std::string strname = "std::";
4286 strname += name;
4287 decl = lh.findClassTemplate(strname,
4288 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4289 : cling::LookupHelper::NoDiagnostics);
4290 }
4291 return 0 != decl;
4292}
4293
4294////////////////////////////////////////////////////////////////////////////////
4295/// Create list of pointers to base class(es) for TClass cl.
4296
4298{
4300 if (cl->fBase) {
4301 return;
4302 }
4304 if (!tci) return;
4306 TList *listOfBase = new TList;
4307 while (t.Next()) {
4308 // if name cannot be obtained no use to put in list
4309 if (t.IsValid() && t.Name()) {
4311 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4312 }
4313 }
4314 // Now that is complete, publish it.
4315 cl->fBase = listOfBase;
4316}
4317
4318////////////////////////////////////////////////////////////////////////////////
4319/// Create list of pointers to enums for TClass cl.
4320
4321void TCling::LoadEnums(TListOfEnums& enumList) const
4322{
4324
4325 const Decl * D;
4326 TClass* cl = enumList.GetClass();
4327 if (cl) {
4328 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4329 }
4330 else {
4331 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4332 }
4333 // Iterate on the decl of the class and get the enums.
4334 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4335 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4336 // Collect all contexts of the namespace.
4337 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4338 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4339 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4340 declIter != declEnd; ++declIter) {
4341 // Iterate on all decls for each context.
4342 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4343 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4344 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4345 // Get name of the enum type.
4346 std::string buf;
4347 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4348 llvm::raw_string_ostream stream(buf);
4349 // Don't trigger fopen of the source file to count lines:
4350 Policy.AnonymousTagLocations = false;
4351 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4352 stream.flush();
4353 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4354 if (!buf.empty()) {
4355 const char* name = buf.c_str();
4356 // Add the enum to the list of loaded enums.
4357 enumList.Get(ED, name);
4358 }
4359 }
4360 }
4361 }
4362 }
4363}
4364
4365////////////////////////////////////////////////////////////////////////////////
4366/// Create list of pointers to function templates for TClass cl.
4367
4369{
4371
4372 const Decl * D;
4373 TListOfFunctionTemplates* funcTempList;
4374 if (cl) {
4375 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4376 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4377 }
4378 else {
4379 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4380 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4381 }
4382 // Iterate on the decl of the class and get the enums.
4383 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4384 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4385 // Collect all contexts of the namespace.
4386 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4387 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4388 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4389 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4390 // Iterate on all decls for each context.
4391 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4392 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4393 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4394 funcTempList->Get(FTD);
4395 }
4396 }
4397 }
4398 }
4399}
4400
4401////////////////////////////////////////////////////////////////////////////////
4402/// Get the scopes representing using declarations of namespace
4403
4404std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4405{
4407 return ci->GetUsingNamespaces();
4408}
4409
4410////////////////////////////////////////////////////////////////////////////////
4411/// Create list of pointers to data members for TClass cl.
4412/// This is now a nop. The creation and updating is handled in
4413/// TListOfDataMembers.
4414
4416{
4417}
4418
4419////////////////////////////////////////////////////////////////////////////////
4420/// Create list of pointers to methods for TClass cl.
4421/// This is now a nop. The creation and updating is handled in
4422/// TListOfFunctions.
4423
4425{
4426}
4427
4428////////////////////////////////////////////////////////////////////////////////
4429/// Update the list of pointers to method for TClass cl
4430/// This is now a nop. The creation and updating is handled in
4431/// TListOfFunctions.
4432
4434{
4435}
4436
4437////////////////////////////////////////////////////////////////////////////////
4438/// Update the list of pointers to data members for TClass cl
4439/// This is now a nop. The creation and updating is handled in
4440/// TListOfDataMembers.
4441
4443{
4444}
4445
4446////////////////////////////////////////////////////////////////////////////////
4447/// Create list of pointers to method arguments for TMethod m.
4448
4450{
4452 if (m->fMethodArgs) {
4453 return;
4454 }
4455 TList *arglist = new TList;
4457 while (t.Next()) {
4458 if (t.IsValid()) {
4460 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4461 }
4462 }
4463 m->fMethodArgs = arglist;
4464}
4465
4466
4467////////////////////////////////////////////////////////////////////////////////
4468/// Generate a TClass for the given class.
4469/// Since the caller has already check the ClassInfo, let it give use the
4470/// result (via the value of emulation) rather than recalculate it.
4471
4472TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4473{
4474// For now the following line would lead to the (unwanted) instantiation
4475// of class template. This could/would need to be resurrected only if
4476// we re-introduce so sort of automatic instantiation. However this would
4477// have to include carefull look at the template parameter to avoid
4478// creating instance we can not really use (if the parameter are only forward
4479// declaration or do not have all the necessary interfaces).
4480
4481 // TClingClassInfo tci(fInterpreter, classname);
4482 // if (1 || !tci.IsValid()) {
4483
4484 Version_t version = 1;
4485 if (TClassEdit::IsSTLCont(classname)) {
4486 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4487 }
4489 TClass *cl = new TClass(classname, version, silent);
4490 if (emulation) {
4492 } else {
4493 // Set the class version if the class is versioned.
4494 // Note that we cannot just call CLASS::Class_Version() as we might not have
4495 // an execution engine (when invoked from rootcling).
4496
4497 // Do not call cl->GetClassVersion(), it has side effects!
4498 Version_t oldvers = cl->fClassVersion;
4499 if (oldvers == version && cl->GetClassInfo()) {
4500 // We have a version and it might need an update.
4502 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4503 // Namespaces don't have class versions.
4504 return cl;
4505 }
4506 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4509 if (!mi.IsValid()) {
4510 if (cl->TestBit(TClass::kIsTObject)) {
4511 Error("GenerateTClass",
4512 "Cannot find %s::Class_Version()! Class version might be wrong.",
4513 cl->GetName());
4514 }
4515 return cl;
4516 }
4517 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4518 *fInterpreter);
4519 if (newvers == -1) {
4520 // Didn't manage to determine the class version from the AST.
4521 // Use runtime instead.
4522 if ((mi.Property() & kIsStatic)
4523 && !fInterpreter->isInSyntaxOnlyMode()) {
4524 // This better be a static function.
4526 callfunc.SetFunc(&mi);
4527 newvers = callfunc.ExecInt(0);
4528 } else {
4529 Error("GenerateTClass",
4530 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4531 cl->GetName());
4532 }
4533 }
4534 if (newvers != oldvers) {
4535 cl->fClassVersion = newvers;
4536 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4537 }
4538 }
4539 }
4540
4541 return cl;
4542
4543// } else {
4544// return GenerateTClass(&tci,silent);
4545// }
4546}
4547
4548#if 0
4549////////////////////////////////////////////////////////////////////////////////
4550
4551static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4552{
4553 includes += info->FileName();
4554
4555 const clang::ClassTemplateSpecializationDecl *templateCl
4556 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4557 if (templateCl) {
4558 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4559 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4560 if (arg.getKind() == clang::TemplateArgument::Type) {
4561 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4562
4563 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4564 // We really need a header file.
4565 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4566 if (argdecl) {
4567 includes += ";";
4568 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4569 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4570 } else {
4571 std::string Result;
4572 llvm::raw_string_ostream OS(Result);
4573 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4574 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4575 }
4576 }
4577 }
4578 }
4579 }
4580}
4581#endif
4582
4583////////////////////////////////////////////////////////////////////////////////
4584/// Generate a TClass for the given class.
4585
4586TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4587{
4588 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4589 if (!info || !info->IsValid()) {
4590 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4591 return 0;
4592 }
4593 // We are in the case where we have AST nodes for this class.
4594 TClass *cl = 0;
4595 std::string classname;
4596 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4597 if (TClassEdit::IsSTLCont(classname)) {
4598#if 0
4599 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4600 // We need to build up the list of required headers, by
4601 // looking at each template arguments.
4602 TString includes;
4603 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4604
4605 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4606 // 0 means success.
4607 cl = TClass::LoadClass(classnam.c_str(), silent);
4608 if (cl == 0) {
4609 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4610 }
4611 }
4612#endif
4613 if (cl == 0) {
4614 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4615 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4617 }
4618 } else {
4619 // For regular class, just create a TClass on the fly ...
4620 // Not quite useful yet, but that what CINT used to do anyway.
4621 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4622 }
4623 // Add the new TClass to the map of declid and TClass*.
4624 if (cl) {
4626 }
4627 return cl;
4628}
4629
4630////////////////////////////////////////////////////////////////////////////////
4631/// Generate the dictionary for the C++ classes listed in the first
4632/// argument (in a semi-colon separated list).
4633/// 'includes' contains a semi-colon separated list of file to
4634/// #include in the dictionary.
4635/// For example:
4636/// ~~~ {.cpp}
4637/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4638/// ~~~
4639/// or
4640/// ~~~ {.cpp}
4641/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4642/// ~~~
4643
4644Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4645{
4646 if (classes == 0 || classes[0] == 0) {
4647 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4648 return 0;
4649 }
4650 // Split the input list
4651 std::vector<std::string> listClasses;
4652 for (
4653 const char* current = classes, *prev = classes;
4654 *current != 0;
4655 ++current
4656 ) {
4657 if (*current == ';') {
4658 listClasses.push_back(std::string(prev, current - prev));
4659 prev = current + 1;
4660 }
4661 else if (*(current + 1) == 0) {
4662 listClasses.push_back(std::string(prev, current + 1 - prev));
4663 prev = current + 1;
4664 }
4665 }
4666 std::vector<std::string> listIncludes;
4667 if (!includes)
4668 includes = "";
4669 for (
4670 const char* current = includes, *prev = includes;
4671 *current != 0;
4672 ++current
4673 ) {
4674 if (*current == ';') {
4675 listIncludes.push_back(std::string(prev, current - prev));
4676 prev = current + 1;
4677 }
4678 else if (*(current + 1) == 0) {
4679 listIncludes.push_back(std::string(prev, current + 1 - prev));
4680 prev = current + 1;
4681 }
4682 }
4683 // Generate the temporary dictionary file
4684 return !TCling_GenerateDictionary(listClasses, listIncludes,
4685 std::vector<std::string>(), std::vector<std::string>());
4686}
4687
4688////////////////////////////////////////////////////////////////////////////////
4689/// Return pointer to cling Decl of global/static variable that is located
4690/// at the address given by addr.
4691
4692TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4693{
4695 DeclId_t d;
4696 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4697
4698 if (cl) {
4699 d = cl->GetDataMember(name);
4700 // We check if the decl of the data member has an annotation which indicates
4701 // an ioname.
4702 // In case this is true, if the name requested is not the ioname, we
4703 // return 0, as if the member did not exist. In some sense we override
4704 // the information in the TClassInfo instance, isolating the typesystem in
4705 // TClass from the one in the AST.
4706 if (const ValueDecl* decl = (const ValueDecl*) d){
4707 std::string ioName;
4708 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4709 if (hasIoName && ioName != name) return 0;
4710 }
4711 return d;
4712 }
4713 // We are looking up for something on the TU scope.
4714 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4715 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4716 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4717 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4718 // are only fulfilling ROOT's understanding for a Data Member.
4719 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4720 // similar as below.
4721 using namespace clang;
4722 Sema& SemaR = fInterpreter->getSema();
4723 DeclarationName DName = &SemaR.Context.Idents.get(name);
4724
4725 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4726 Sema::ForExternalRedeclaration);
4727
4728 // Could trigger deserialization of decls.
4729 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4730 cling::utils::Lookup::Named(&SemaR, R);
4731
4732 LookupResult::Filter F = R.makeFilter();
4733 // Filter the data-member looking decls.
4734 while (F.hasNext()) {
4735 NamedDecl *D = F.next();
4736 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4737 isa<IndirectFieldDecl>(D))
4738 continue;
4739 F.erase();
4740 }
4741 F.done();
4742
4743 if (R.isSingleResult())
4744 return R.getFoundDecl();
4745 return 0;
4746}
4747
4748////////////////////////////////////////////////////////////////////////////////
4749/// Return pointer to cling Decl of global/static variable that is located
4750/// at the address given by addr.
4751
4753{
4755
4756 const clang::Decl* possibleEnum = 0;
4757 // FInd the context of the decl.
4758 if (cl) {
4760 if (cci) {
4761 const clang::DeclContext* dc = 0;
4762 if (const clang::Decl* D = cci->GetDecl()) {
4763 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4764 dc = dyn_cast<clang::RecordDecl>(D);
4765 }
4766 }
4767 if (dc) {
4768 // If it is a data member enum.
4769 // Could trigger deserialization of decls.
4770 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4771 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4772 } else {
4773 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4774 }
4775 }
4776 } else {
4777 // If it is a global enum.
4778 // Could trigger deserialization of decls.
4779 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4780 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4781 }
4782 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4783 && isa<clang::EnumDecl>(possibleEnum)) {
4784 return possibleEnum;
4785 }
4786 return 0;
4787}
4788
4789////////////////////////////////////////////////////////////////////////////////
4790/// Return pointer to cling DeclId for a global value
4791
4792TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4793{
4794 if (!gv) return 0;
4795
4796 llvm::StringRef mangled_name = gv->getName();
4797
4798 int err = 0;
4799 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4800 if (err) {
4801 if (err == -2) {
4802 // It might simply be an unmangled global name.
4803 DeclId_t d;
4805 d = gcl.GetDataMember(mangled_name.str().c_str());
4806 return d;
4807 }
4808 return 0;
4809 }
4810
4811 std::string scopename(demangled_name_c);
4812 free(demangled_name_c);
4813
4814 //
4815 // Separate out the class or namespace part of the
4816 // function name.
4817 //
4818 std::string dataname;
4819
4820 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4821 scopename.erase(0, sizeof("typeinfo for ")-1);
4822 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4823 scopename.erase(0, sizeof("vtable for ")-1);
4824 } else {
4825 // See if it is a function
4826 std::string::size_type pos = scopename.rfind('(');
4827 if (pos != std::string::npos) {
4828 return 0;
4829 }
4830 // Separate the scope and member name
4831 pos = scopename.rfind(':');
4832 if (pos != std::string::npos) {
4833 if ((pos != 0) && (scopename[pos-1] == ':')) {
4834 dataname = scopename.substr(pos+1);
4835 scopename.erase(pos-1);
4836 }
4837 } else {
4838 scopename.clear();
4839 dataname = scopename;
4840 }
4841 }
4842 //fprintf(stderr, "name: '%s'\n", name.c_str());
4843 // Now we have the class or namespace name, so do the lookup.
4844
4845
4846 DeclId_t d;
4847 if (scopename.size()) {
4848 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4849 d = cl.GetDataMember(dataname.c_str());
4850 }
4851 else {
4853 d = gcl.GetDataMember(dataname.c_str());
4854 }
4855 return d;
4856}
4857
4858////////////////////////////////////////////////////////////////////////////////
4859/// NOT IMPLEMENTED.
4860
4862{
4863 Error("GetDataMemberWithValue()", "not implemented");
4864 return 0;
4865}
4866
4867////////////////////////////////////////////////////////////////////////////////
4868/// Return pointer to cling DeclId for a data member with a given name.
4869
4871{
4872 // NOT IMPLEMENTED.
4873 Error("GetDataMemberAtAddr()", "not implemented");
4874 return 0;
4875}
4876
4877////////////////////////////////////////////////////////////////////////////////
4878/// Return the cling mangled name for a method of a class with parameters
4879/// params (params is a string of actual arguments, not formal ones). If the
4880/// class is 0 the global function list will be searched.
4881
4882TString TCling::GetMangledName(TClass* cl, const char* method,
4883 const char* params, Bool_t objectIsConst /* = kFALSE */)
4884{
4887 if (cl) {
4888 Longptr_t offset;
4889 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4890 &offset);
4891 }
4892 else {
4894 Longptr_t offset;
4895 func.SetFunc(&gcl, method, params, &offset);
4896 }
4898 if (!mi) return "";
4899 TString mangled_name( mi->GetMangledName() );
4900 delete mi;
4901 return mangled_name;
4902}
4903
4904////////////////////////////////////////////////////////////////////////////////
4905/// Return the cling mangled name for a method of a class with a certain
4906/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4907/// list will be searched.
4908
4910 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4911 EFunctionMatchMode mode /* = kConversionMatch */)
4912{
4914 if (cl) {
4915 return ((TClingClassInfo*)cl->GetClassInfo())->
4916 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4917 }
4919 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4920}
4921
4922////////////////////////////////////////////////////////////////////////////////
4923/// Return pointer to cling interface function for a method of a class with
4924/// parameters params (params is a string of actual arguments, not formal
4925/// ones). If the class is 0 the global function list will be searched.
4926
4927void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4928 const char* params, Bool_t objectIsConst /* = kFALSE */)
4929{
4932 if (cl) {
4933 Longptr_t offset;
4934 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4935 &offset);
4936 }
4937 else {
4939 Longptr_t offset;
4940 func.SetFunc(&gcl, method, params, &offset);
4941 }
4942 return (void*) func.InterfaceMethod();
4943}
4944
4945////////////////////////////////////////////////////////////////////////////////
4946/// Return pointer to cling interface function for a method of a class with
4947/// a certain name.
4948
4949TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4950{
4952 DeclId_t f;
4953 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4954 if (cl) {
4955 f = cl->GetMethod(method).GetDeclId();
4956 }
4957 else {
4959 f = gcl.GetMethod(method).GetDeclId();
4960 }
4961 return f;
4962
4963}
4964
4965////////////////////////////////////////////////////////////////////////////////
4966/// Insert overloads of name in cl to res.
4967
4968void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
4969 std::vector<DeclId_t>& res) const
4970{
4971 clang::Sema& S = fInterpreter->getSema();
4972 clang::ASTContext& Ctx = S.Context;
4973 const clang::Decl* CtxDecl
4974 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4975 Ctx.getTranslationUnitDecl();
4976 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4977 const clang::DeclContext* DeclCtx = RecDecl;
4978
4979 if (!DeclCtx)
4980 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4981 if (!DeclCtx) return;
4982
4983 clang::DeclarationName DName;
4984 // The DeclarationName is funcname, unless it's a ctor or dtor.
4985 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
4986
4987 if (RecDecl) {
4988 if (RecDecl->getNameAsString() == funcname) {
4989 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4990 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4991 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
4992 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4993 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4994 } else {
4995 DName = &Ctx.Idents.get(funcname);
4996 }
4997 } else {
4998 DName = &Ctx.Idents.get(funcname);
4999 }
5000
5001 // NotForRedeclaration: we want to find names in inline namespaces etc.
5002 clang::LookupResult R(S, DName, clang::SourceLocation(),
5003 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5004 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5005 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5006 if (R.empty()) return;
5007 R.resolveKind();
5008 res.reserve(res.size() + (R.end() - R.begin()));
5009 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5010 IR != ER; ++IR) {
5011 if (const clang::FunctionDecl* FD
5012 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5013 if (!FD->getDescribedFunctionTemplate()) {
5014 res.push_back(FD);
5015 }
5016 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5017 // FIXME: multi-level using
5018 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5019 res.push_back(USD);
5020 }
5021 }
5022 }
5023}
5024
5025////////////////////////////////////////////////////////////////////////////////
5026/// Return pointer to cling interface function for a method of a class with
5027/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5028/// function list will be searched.
5029
5031 const char* proto,
5032 Bool_t objectIsConst /* = kFALSE */,
5033 EFunctionMatchMode mode /* = kConversionMatch */)
5034{
5036 void* f;
5037 if (cl) {
5038 f = ((TClingClassInfo*)cl->GetClassInfo())->
5039 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
5040 }
5041 else {
5043 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
5044 }
5045 return f;
5046}
5047
5048////////////////////////////////////////////////////////////////////////////////
5049/// Return pointer to cling DeclId for a method of a class with
5050/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5051/// function list will be searched.
5052
5053TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5054 const char* params,
5055 Bool_t objectIsConst /* = kFALSE */)
5056{
5058 DeclId_t f;
5059 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5060 if (cl) {
5061 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5062 }
5063 else {
5065 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5066 }
5067 return f;
5068}
5069
5070////////////////////////////////////////////////////////////////////////////////
5071/// Return pointer to cling interface function for a method of a class with
5072/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5073/// function list will be searched.
5074
5075TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5076 const char* proto,
5077 Bool_t objectIsConst /* = kFALSE */,
5078 EFunctionMatchMode mode /* = kConversionMatch */)
5079{
5081 DeclId_t f;
5082 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5083 if (cl) {
5084 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5085 }
5086 else {
5088 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5089 }
5090 return f;
5091}
5092
5093////////////////////////////////////////////////////////////////////////////////
5094/// Return pointer to cling interface function for a method of a class with
5095/// a certain name.
5096
5097TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5098{
5100 DeclId_t f;
5101 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5102 if (cl) {
5103 f = cl->GetFunctionTemplate(name);
5104 }
5105 else {
5107 f = gcl.GetFunctionTemplate(name);
5108 }
5109 return f;
5110
5111}
5112
5113////////////////////////////////////////////////////////////////////////////////
5114/// The 'name' is known to the interpreter, this function returns
5115/// the internal version of this name (usually just resolving typedefs)
5116/// This is used in particular to synchronize between the name used
5117/// by rootcling and by the run-time environment (TClass)
5118/// Return 0 if the name is not known.
5119
5120void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5121{
5122 output.clear();
5123
5125
5127 if (!cl.IsValid()) {
5128 return ;
5129 }
5130 if (full) {
5132 return;
5133 }
5134 // Well well well, for backward compatibility we need to act a bit too
5135 // much like CINT.
5138
5139 return;
5140}
5141
5142////////////////////////////////////////////////////////////////////////////////
5143/// Execute a global function with arguments params.
5144///
5145/// FIXME: The cint-based version of this code does not check if the
5146/// SetFunc() call works, and does not do any real checking
5147/// for errors from the Exec() call. It did fetch the most
5148/// recent cint security error and return that in error, but
5149/// this does not really translate well to cling/clang. We
5150/// should enhance these interfaces so that we can report
5151/// compilation and runtime errors properly.
5152
5153void TCling::Execute(const char* function, const char* params, int* error)
5154{
5156 if (error) {
5157 *error = TInterpreter::kNoError;
5158 }
5160 Longptr_t offset = 0L;
5162 func.SetFunc(&cl, function, params, &offset);
5163 func.Exec(0);
5164}
5165
5166////////////////////////////////////////////////////////////////////////////////
5167/// Execute a method from class cl with arguments params.
5168///
5169/// FIXME: The cint-based version of this code does not check if the
5170/// SetFunc() call works, and does not do any real checking
5171/// for errors from the Exec() call. It did fetch the most
5172/// recent cint security error and return that in error, but
5173/// this does not really translate well to cling/clang. We
5174/// should enhance these interfaces so that we can report
5175/// compilation and runtime errors properly.
5176
5177void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5178 const char* params, Bool_t objectIsConst, int* error)
5179{
5181 if (error) {
5182 *error = TInterpreter::kNoError;
5183 }
5184 // If the actual class of this object inherits 2nd (or more) from TObject,
5185 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5186 // hence gInterpreter->Execute will improperly correct the offset.
5187 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5188 Longptr_t offset = 0L;
5190 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5191 void* address = (void*)((Longptr_t)addr + offset);
5192 func.Exec(address);
5193}
5194
5195////////////////////////////////////////////////////////////////////////////////
5196
5197void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5198 const char* params, int* error)
5199{
5200 Execute(obj,cl,method,params,false,error);
5201}
5202
5203////////////////////////////////////////////////////////////////////////////////
5204/// Execute a method from class cl with the arguments in array params
5205/// (params[0] ... params[n] = array of TObjString parameters).
5206/// Convert the TObjArray array of TObjString parameters to a character
5207/// string of comma separated parameters.
5208/// The parameters of type 'char' are enclosed in double quotes and all
5209/// internal quotes are escaped.
5210
5211void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5212 TObjArray* params, int* error)
5213{
5214 if (!method) {
5215 Error("Execute", "No method was defined");
5216 return;
5217 }
5218 TList* argList = method->GetListOfMethodArgs();
5219 // Check number of actual parameters against of expected formal ones
5220
5221 Int_t nparms = argList->LastIndex() + 1;
5222 Int_t argc = params ? params->GetEntries() : 0;
5223
5224 if (argc > nparms) {
5225 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5226 return;
5227 }
5228 if (nparms != argc) {
5229 // Let's see if the 'missing' argument are all defaulted.
5230 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5231 assert(nparms > 0);
5232
5233 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5234 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5235 // There is a default value for the first missing
5236 // argument, so we are fine.
5237 } else {
5238 Int_t firstDefault = -1;
5239 for (Int_t i = 0; i < nparms; i ++) {
5240 arg = (TMethodArg *) argList->At( i );
5241 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5242 firstDefault = i;
5243 break;
5244 }
5245 }
5246 if (firstDefault >= 0) {
5247 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);
5248 } else {
5249 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5250 }
5251 return;
5252 }
5253 }
5254
5255 const char* listpar = "";
5256 TString complete(10);
5257 if (params) {
5258 // Create a character string of parameters from TObjArray
5259 TIter next(params);
5260 for (Int_t i = 0; i < argc; i ++) {
5261 TMethodArg* arg = (TMethodArg*) argList->At(i);
5263 TObjString* nxtpar = (TObjString*) next();
5264 if (i) {
5265 complete += ',';
5266 }
5267 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5268 TString chpar('\"');
5269 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5270 // At this point we have to check if string contains \\"
5271 // and apply some more sophisticated parser. Not implemented yet!
5272 complete += chpar;
5273 complete += '\"';
5274 }
5275 else {
5276 complete += nxtpar->String();
5277 }
5278 }
5279 listpar = complete.Data();
5280 }
5281
5282 // And now execute it.
5284 if (error) {
5285 *error = TInterpreter::kNoError;
5286 }
5287 // If the actual class of this object inherits 2nd (or more) from TObject,
5288 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5289 // hence gInterpreter->Execute will improperly correct the offset.
5290 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5292 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5293 func.Init(*minfo);
5294 func.SetArgs(listpar);
5295 // Now calculate the 'this' pointer offset for the method
5296 // when starting from the class described by cl.
5297 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5298 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5299 void* address = (void*)((Longptr_t)addr + offset);
5300 func.Exec(address);
5301}
5302
5303////////////////////////////////////////////////////////////////////////////////
5304
5305void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5306 const void* args[] /*=0*/,
5307 int nargs /*=0*/,
5308 void* ret/*= 0*/) const
5309{
5310 if (!method) {
5311 Error("ExecuteWithArgsAndReturn", "No method was defined");
5312 return;
5313 }
5314
5315 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5316 TClingCallFunc func(*minfo,*fNormalizedCtxt);
5317 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5318}
5319
5320////////////////////////////////////////////////////////////////////////////////
5321/// Execute a cling macro.
5322
5323Longptr_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
5324{
5326 fCurExecutingMacros.push_back(filename);
5327 Longptr_t result = TApplication::ExecuteFile(filename, (int*)error);
5328 fCurExecutingMacros.pop_back();
5329 return result;
5330}
5331
5332////////////////////////////////////////////////////////////////////////////////
5333/// Return the file name of the current un-included interpreted file.
5334/// See the documentation for GetCurrentMacroName().
5335
5337{
5338 Warning("GetTopLevelMacroName", "Must change return type!");
5339 return fCurExecutingMacros.back();
5340}
5341
5342////////////////////////////////////////////////////////////////////////////////
5343/// Return the file name of the currently interpreted file,
5344/// included or not. Example to illustrate the difference between
5345/// GetCurrentMacroName() and GetTopLevelMacroName():
5346/// ~~~ {.cpp}
5347/// void inclfile() {
5348/// std::cout << "In inclfile.C" << std::endl;
5349/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5350/// TCling::GetCurrentMacroName() << std::endl;
5351/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5352/// TCling::GetTopLevelMacroName() << std::endl;
5353/// }
5354/// ~~~
5355/// ~~~ {.cpp}
5356/// void mymacro() {
5357/// std::cout << "In mymacro.C" << std::endl;
5358/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5359/// TCling::GetCurrentMacroName() << std::endl;
5360/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5361/// TCling::GetTopLevelMacroName() << std::endl;
5362/// std::cout << " Now calling inclfile..." << std::endl;
5363/// gInterpreter->ProcessLine(".x inclfile.C");;
5364/// }
5365/// ~~~
5366/// Running mymacro.C will print:
5367///
5368/// ~~~ {.cpp}
5369/// root [0] .x mymacro.C
5370/// ~~~
5371/// In mymacro.C
5372/// ~~~ {.cpp}
5373/// TCling::GetCurrentMacroName() returns ./mymacro.C
5374/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5375/// ~~~
5376/// Now calling inclfile...
5377/// In inclfile.h
5378/// ~~~ {.cpp}
5379/// TCling::GetCurrentMacroName() returns inclfile.C
5380/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5381/// ~~~
5382
5384{
5385#if defined(R__MUST_REVISIT)
5386#if R__MUST_REVISIT(6,0)
5387 Warning("GetCurrentMacroName", "Must change return type!");
5388#endif
5389#endif
5390 return fCurExecutingMacros.back();
5391}
5392
5393////////////////////////////////////////////////////////////////////////////////
5394/// Return the absolute type of typeDesc.
5395/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5396/// You need to use the result immediately before it is being overwritten.
5397
5398const char* TCling::TypeName(const char* typeDesc)
5399{
5400 TTHREAD_TLS_DECL(std::string,t);
5401
5402 if (!strstr(typeDesc, "(*)(")) {
5403 const char *s = strchr(typeDesc, ' ');
5404 const char *template_start = strchr(typeDesc, '<');
5405 if (!strcmp(typeDesc, "long long")) {
5406 t = typeDesc;
5407 }
5408 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5409 t = typeDesc;
5410 }
5411 // s is the position of the second 'word' (if any)
5412 // except in the case of templates where there will be a space
5413 // just before any closing '>': eg.
5414 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5415 else if (s && (template_start == 0 || (s < template_start))) {
5416 t = s + 1;
5417 }
5418 else {
5419 t = typeDesc;
5420 }
5421 }
5422 else {
5423 t = typeDesc;
5424 }
5425 auto l = t.length();
5426 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5427 --l;
5428 t.resize(l);
5429 return t.c_str(); // NOLINT
5430}
5431
5432static bool requiresRootMap(const char* rootmapfile)
5433{
5434 assert(rootmapfile && *rootmapfile);
5435
5436 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5437 libName.consume_back(".rootmap");
5438
5439 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5440}
5441
5442////////////////////////////////////////////////////////////////////////////////
5443/// Read and parse a rootmapfile in its new format, and return 0 in case of
5444/// success, -1 if the file has already been read, and -3 in case its format
5445/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5446/// error.
5447
5448int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5449{
5450 if (!(rootmapfile && *rootmapfile))
5451 return 0;
5452
5453 if (!requiresRootMap(rootmapfile))
5454 return 0; // success
5455
5456 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5457 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5458
5459 std::string rootmapfileNoBackslash(rootmapfile);
5460#ifdef _MSC_VER
5461 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5462#endif
5463 // Add content of a specific rootmap file
5464 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5465 return -1;
5466
5467 // Line 1 is `{ decls }`
5468 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5469
5470 std::ifstream file(rootmapfileNoBackslash);
5471 std::string line;
5472 line.reserve(200);
5473 std::string lib_name;
5474 line.reserve(100);
5475 bool newFormat = false;
5476 while (getline(file, line, '\n')) {
5477 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5478 file.close();
5479 return -3; // old format
5480 }
5481 newFormat = true;
5482
5483 if (line.compare(0, 9, "{ decls }") == 0) {
5484 // forward declarations
5485
5486 while (getline(file, line, '\n')) {
5487 if (line[0] == '[')
5488 break;
5489 if (!uniqueString) {
5490 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5491 rootmapfileNoBackslash.c_str());
5492 return -4;
5493 }
5494 if (!lineDirective.empty())
5495 uniqueString->Append(lineDirective);
5496 uniqueString->Append(line + '\n');
5497 }
5498 }
5499 const char firstChar = line[0];
5500 if (firstChar == '[') {
5501 // new section (library)
5502 auto brpos = line.find(']');
5503 if (brpos == string::npos)
5504 continue;
5505 lib_name = line.substr(1, brpos - 1);
5506 size_t nspaces = 0;
5507 while (lib_name[nspaces] == ' ')
5508 ++nspaces;
5509 if (nspaces)
5510 lib_name.replace(0, nspaces, "");
5511 if (gDebug > 3) {
5512 TString lib_nameTstr(lib_name.c_str());
5513 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5514 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5515 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5516 if (wlib) {
5517 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5518 } else {
5519 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5520 }
5521 delete[] wlib;
5522 delete tokens;
5523 }
5524 } else {
5525 auto keyLenIt = keyLenMap.find(firstChar);
5526 if (keyLenIt == keyLenMap.end())
5527 continue;
5528 unsigned int keyLen = keyLenIt->second;
5529 // Do not make a copy, just start after the key
5530 const char *keyname = line.c_str() + keyLen;
5531 if (gDebug > 6)
5532 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5533 TEnvRec *isThere = fMapfile->Lookup(keyname);
5534 if (isThere) {
5535 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5536 if (firstChar == 'n') {
5537 if (gDebug > 3)
5538 Info("ReadRootmapFile", "namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5539 isThere->GetValue());
5540 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5541 lib_name += " ";
5542 lib_name += isThere->GetValue();
5543 fMapfile->SetValue(keyname, lib_name.c_str());
5544 } else if (!TClassEdit::IsSTLCont(keyname)) {
5545 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5546 keyname, lib_name.c_str(), isThere->GetValue());
5547 }
5548 } else { // the same key for the same lib
5549 if (gDebug > 3)
5550 Info("ReadRootmapFile", "Key %s was already defined for %s", keyname, lib_name.c_str());
5551 }
5552 } else {
5553 fMapfile->SetValue(keyname, lib_name.c_str());
5554 }
5555 }
5556 }
5557 file.close();
5558 return 0;
5559}
5560
5561////////////////////////////////////////////////////////////////////////////////
5562/// Create a resource table and read the (possibly) three resource files,
5563/// i.e.\ $ROOTSYS/etc/system<name> (or ROOTETCDIR/system<name>), $HOME/<name>
5564/// and $PWD/<name>. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5565/// can read additional user defined resource files by creating additional TEnv
5566/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5567/// the $HOME/<name> resource file will be skipped. This might be useful in
5568/// case the home directory resides on an automounted remote file system
5569/// and one wants to avoid the file system from being mounted.
5570
5572{
5573 assert(requiresRootMap(name) && "We have a module!");
5574
5575 if (!requiresRootMap(name))
5576 return;
5577
5579
5581
5582 TString sname = "system";
5583 sname += name;
5584 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5585
5586 Int_t ret = ReadRootmapFile(s);
5587 if (ret == -3) // old format
5589 delete [] s;
5590 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5592 ret = ReadRootmapFile(s);
5593 if (ret == -3) // old format
5595 delete [] s;
5596 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5597 ret = ReadRootmapFile(name);
5598 if (ret == -3) // old format
5600 }
5601 } else {
5602 ret = ReadRootmapFile(name);
5603 if (ret == -3) // old format
5605 }
5606 fMapfile->IgnoreDuplicates(ignore);
5607}
5608
5609
5610namespace {
5611 using namespace clang;
5612
5613 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5614 // This class is to be considered an helper for AutoLoading.
5615 // It is a recursive visitor is used to inspect namespaces and specializations
5616 // coming from forward declarations in rootmaps and to set the external visible
5617 // storage flag for them.
5618 public:
5619 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5620 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5621 // We want to enable the external lookup for this namespace
5622 // because it may shadow the lookup of other names contained
5623 // in that namespace
5624
5625 nsDecl->setHasExternalVisibleStorage();
5626 fNSSet.insert(nsDecl);
5627 return true;
5628 }
5629 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5630 // We want to enable the external lookup for this specialization
5631 // because we can provide a definition for it!
5632 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5633 //SpecSet.insert(specDecl);
5634 specDecl->setHasExternalLexicalStorage();
5635
5636 // No need to recurse. On the contrary, recursing is actively harmful:
5637 // NOTE: must not recurse to prevent this visitor from triggering loading from
5638 // the external AST source (i.e. autoloading). This would be triggered right here,
5639 // before autoloading is even set up, as rootmap file parsing happens before that.
5640 // Even if autoloading is off and has no effect, triggering loading from external
5641 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5642 // from subsequent autoloads!
5643 return false;
5644 }
5645 private:
5646 std::unordered_set<const NamespaceDecl*>& fNSSet;
5647 };
5648}
5649
5650////////////////////////////////////////////////////////////////////////////////
5651/// Load map between class and library. If rootmapfile is specified a
5652/// specific rootmap file can be added (typically used by ACLiC).
5653/// In case of error -1 is returned, 0 otherwise.
5654/// The interpreter uses this information to automatically load the shared
5655/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5656
5657Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5658{
5659 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5660 return 0;
5661
5663
5664 // open the [system].rootmap files
5665 if (!fMapfile) {
5666 fMapfile = new TEnv();
5670 InitRootmapFile(".rootmap");
5671 }
5672
5673 // Prepare a list of all forward declarations for cling
5674 // For some experiments it is easily as big as 500k characters. To be on the
5675 // safe side, we go for 1M.
5676 TUniqueString uniqueString(1048576);
5677
5678 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5679 // A rootmap file must end with the string ".rootmap".
5680 TString ldpath = gSystem->GetDynamicPath();
5681 if (ldpath != fRootmapLoadPath) {
5682 fRootmapLoadPath = ldpath;
5683#ifdef WIN32
5684 TObjArray* paths = ldpath.Tokenize(";");
5685#else
5686 TObjArray* paths = ldpath.Tokenize(":");
5687#endif
5688 TString d;
5689 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5690 d = ((TObjString *)paths->At(i))->GetString();
5691 // check if directory already scanned
5692 Int_t skip = 0;
5693 for (Int_t j = 0; j < i; j++) {
5694 TString pd = ((TObjString *)paths->At(j))->GetString();
5695 if (pd == d) {
5696 skip++;
5697 break;
5698 }
5699 }
5700 if (!skip) {
5701 void* dirp = gSystem->OpenDirectory(d);
5702 if (dirp) {
5703 if (gDebug > 3) {
5704 Info("LoadLibraryMap", "%s", d.Data());
5705 }
5706 const char* f1;
5707 while ((f1 = gSystem->GetDirEntry(dirp))) {
5708 TString f = f1;
5709 if (f.EndsWith(".rootmap")) {
5710 TString p;
5711 p = d + "/" + f;
5713 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5714 if (gDebug > 4) {
5715 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5716 }
5717 Int_t ret = ReadRootmapFile(p, &uniqueString);
5718
5719 if (ret == 0)
5721 if (ret == -3) {
5722 // old format
5724 fRootmapFiles->Add(new TNamed(f, p));
5725 }
5726 }
5727 // else {
5728 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5729 // fRootmapFiles->FindObject(f)->ls();
5730 // }
5731 }
5732 }
5733 if (f.BeginsWith("rootmap")) {
5734 TString p;
5735 p = d + "/" + f;
5736 FileStat_t stat;
5737 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5738 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5739 }
5740 }
5741 }
5742 }
5743 gSystem->FreeDirectory(dirp);
5744 }
5745 }
5746 delete paths;
5747 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5748 return -1;
5749 }
5750 }
5751 if (rootmapfile && *rootmapfile) {
5752 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5753 if (res == 0) {
5754 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5755 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5756 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5757 }
5758 else if (res == -3) {
5759 // old format
5761 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5762 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5763 fMapfile->IgnoreDuplicates(ignore);
5764 }
5765 }
5766 TEnvRec* rec;
5767 TIter next(fMapfile->GetTable());
5768 while ((rec = (TEnvRec*) next())) {
5769 TString cls = rec->GetName();
5770 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5771 // get the first lib from the list of lib and dependent libs
5772 TString libs = rec->GetValue();
5773 if (libs == "") {
5774 continue;
5775 }
5776 TString delim(" ");
5777 TObjArray* tokens = libs.Tokenize(delim);
5778 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5779 // convert "@@" to "::", we used "@@" because TEnv
5780 // considers "::" a terminator
5781 cls.Remove(0, 8);
5782 cls.ReplaceAll("@@", "::");
5783 // convert "-" to " ", since class names may have
5784 // blanks and TEnv considers a blank a terminator
5785 cls.ReplaceAll("-", " ");
5786 if (gDebug > 6) {
5787 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5788 if (wlib) {
5789 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5790 }
5791 else {
5792 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5793 }
5794 delete[] wlib;
5795 }
5796 delete tokens;
5797 }
5798 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5799 cls.Remove(0, 8);
5800 // convert "-" to " ", since class names may have
5801 // blanks and TEnv considers a blank a terminator
5802 cls.ReplaceAll("-", " ");
5803 fInterpreter->declare(cls.Data());
5804 }
5805 }
5806
5807 // Process the forward declarations collected
5808 cling::Transaction* T = nullptr;
5809 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5810 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5811
5812 if (compRes!=cling::Interpreter::kSuccess){
5813 Warning("LoadLibraryMap",
5814 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5815 }
5816
5817 if (T) {
5818 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5819 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5820 if (declIt->m_DGR.isSingleDecl()) {
5821 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5822 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5823 evsAdder.TraverseDecl(D);
5824 }
5825 }
5826 }
5827 }
5828 }
5829
5830 // clear duplicates
5831
5832 return 0;
5833}
5834
5835////////////////////////////////////////////////////////////////////////////////
5836/// Scan again along the dynamic path for library maps. Entries for the loaded
5837/// shared libraries are unloaded first. This can be useful after reseting
5838/// the dynamic path through TSystem::SetDynamicPath()
5839/// In case of error -1 is returned, 0 otherwise.
5840
5842{
5845 return 0;
5846}
5847
5848////////////////////////////////////////////////////////////////////////////////
5849/// Reload the library map entries coming from all the loaded shared libraries,
5850/// after first unloading the current ones.
5851/// In case of error -1 is returned, 0 otherwise.
5852
5854{
5855 const TString sharedLibLStr = GetSharedLibs();
5856 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5857 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5858 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5859 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5860 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5861 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5862 if (ret < 0) {
5863 continue;
5864 }
5865 TString rootMapBaseStr = sharedLibBaseStr;
5866 if (sharedLibBaseStr.EndsWith(".dll")) {
5867 rootMapBaseStr.ReplaceAll(".dll", "");
5868 }
5869 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5870 rootMapBaseStr.ReplaceAll(".DLL", "");
5871 }
5872 else if (sharedLibBaseStr.EndsWith(".so")) {
5873 rootMapBaseStr.ReplaceAll(".so", "");
5874 }
5875 else if (sharedLibBaseStr.EndsWith(".sl")) {
5876 rootMapBaseStr.ReplaceAll(".sl", "");
5877 }
5878 else if (sharedLibBaseStr.EndsWith(".dl")) {
5879 rootMapBaseStr.ReplaceAll(".dl", "");
5880 }
5881 else if (sharedLibBaseStr.EndsWith(".a")) {
5882 rootMapBaseStr.ReplaceAll(".a", "");
5883 }
5884 else {
5885 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5886 delete sharedLibL;
5887 return -1;
5888 }
5889 rootMapBaseStr += ".rootmap";
5890 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5891 if (!rootMap) {
5892 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5893 delete[] rootMap;
5894 delete sharedLibL;
5895 return -1;
5896 }
5897 const Int_t status = LoadLibraryMap(rootMap);
5898 if (status < 0) {
5899 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5900 delete[] rootMap;
5901 delete sharedLibL;
5902 return -1;
5903 }
5904 delete[] rootMap;
5905 }
5906 delete sharedLibL;
5907 return 0;
5908}
5909
5910////////////////////////////////////////////////////////////////////////////////
5911/// Unload the library map entries coming from all the loaded shared libraries.
5912/// Returns 0 if succesful
5913
5915{
5916 const TString sharedLibLStr = GetSharedLibs();
5917 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5918 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5919 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5920 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5921 UnloadLibraryMap(sharedLibBaseStr);
5922 }
5923 delete sharedLibL;
5924 return 0;
5925}
5926
5927////////////////////////////////////////////////////////////////////////////////
5928/// Unload library map entries coming from the specified library.
5929/// Returns -1 in case no entries for the specified library were found,
5930/// 0 otherwise.
5931
5933{
5934 if (!fMapfile || !library || !*library) {
5935 return 0;
5936 }
5937 TString libname(library);
5938 Ssiz_t idx = libname.Last('.');
5939 if (idx != kNPOS) {
5940 libname.Remove(idx);
5941 }
5942 size_t len = libname.Length();
5943 TEnvRec *rec;
5944 TIter next(fMapfile->GetTable());
5946 Int_t ret = 0;
5947 while ((rec = (TEnvRec *) next())) {
5948 TString cls = rec->GetName();
5949 if (cls.Length() > 2) {
5950 // get the first lib from the list of lib and dependent libs
5951 TString libs = rec->GetValue();
5952 if (libs == "") {
5953 continue;
5954 }
5955 TString delim(" ");
5956 TObjArray* tokens = libs.Tokenize(delim);
5957 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5958 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5959 // convert "@@" to "::", we used "@@" because TEnv
5960 // considers "::" a terminator
5961 cls.Remove(0, 8);
5962 cls.ReplaceAll("@@", "::");
5963 // convert "-" to " ", since class names may have
5964 // blanks and TEnv considers a blank a terminator
5965 cls.ReplaceAll("-", " ");
5966 }
5967 if (!strncmp(lib, libname.Data(), len)) {
5968 if (fMapfile->GetTable()->Remove(rec) == 0) {
5969 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
5970 ret = -1;
5971 }
5972 }
5973 delete tokens;
5974 }
5975 }
5976 if (ret >= 0) {
5977 TString library_rootmap(library);
5978 if (!library_rootmap.EndsWith(".rootmap"))
5979 library_rootmap.Append(".rootmap");
5980 TNamed* mfile = 0;
5981 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5982 fRootmapFiles->Remove(mfile);
5983 delete mfile;
5984 }
5986 }
5987 return ret;
5988}
5989
5990////////////////////////////////////////////////////////////////////////////////
5991/// Register the AutoLoading information for a class.
5992/// libs is a space separated list of libraries.
5993
5994Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
5995{
5996 if (!cls || !*cls)
5997 return 0;
5998
5999 TString key = TString("Library.") + cls;
6000 // convert "::" to "@@", we used "@@" because TEnv
6001 // considers "::" a terminator
6002 key.ReplaceAll("::", "@@");
6003 // convert "-" to " ", since class names may have
6004 // blanks and TEnv considers a blank a terminator
6005 key.ReplaceAll(" ", "-");
6006
6008 if (!fMapfile) {
6009 fMapfile = new TEnv();
6011
6014
6015 InitRootmapFile(".rootmap");
6016 }
6017 //fMapfile->SetValue(key, libs);
6018 fMapfile->SetValue(cls, libs);
6019 return 1;
6020}
6021
6022////////////////////////////////////////////////////////////////////////////////
6023/// Demangle the name (from the typeinfo) and then request the class
6024/// via the usual name based interface (TClass::GetClass).
6025
6026TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6027{
6028 int err = 0;
6029 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6030 if (err) return 0;
6031 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6032 free(demangled_name);
6033 return theClass;
6034}
6035
6036////////////////////////////////////////////////////////////////////////////////
6037/// Load library containing the specified class. Returns 0 in case of error
6038/// and 1 in case if success.
6039
6040Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6041{
6042 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6043
6044 int err = 0;
6045 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6046 if (err) {
6047 return 0;
6048 }
6049
6050 std::string demangled_name(demangled_name_c);
6051 free(demangled_name_c);
6052
6053 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6054 // shortened name.
6056 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6057
6058 // No need to worry about typedef, they aren't any ... but there are
6059 // inlined namespaces ...
6060
6061 Int_t result = AutoLoad(demangled_name.c_str());
6062 if (result == 0) {
6063 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6064 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6065 }
6066
6067 return result;
6068}
6069
6070////////////////////////////////////////////////////////////////////////////////
6071// Get the list of 'published'/'known' library for the class and load them.
6073{
6074 Int_t status = 0;
6075
6076 // lookup class to find list of dependent libraries
6077 TString deplibs = gCling->GetClassSharedLibs(cls);
6078 if (!deplibs.IsNull()) {
6079 TString delim(" ");
6080 TObjArray* tokens = deplibs.Tokenize(delim);
6081 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6082 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6083 if (gROOT->LoadClass(cls, deplib) == 0) {
6084 if (gDebug > 0) {
6085 gCling->Info("TCling::AutoLoad",
6086 "loaded dependent library %s for %s", deplib, cls);
6087 }
6088 }
6089 else {
6090 gCling->Error("TCling::AutoLoad",
6091 "failure loading dependent library %s for %s",
6092 deplib, cls);
6093 }
6094 }
6095 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6096 if (lib && lib[0]) {
6097 if (gROOT->LoadClass(cls, lib) == 0) {
6098 if (gDebug > 0) {
6099 gCling->Info("TCling::AutoLoad",
6100 "loaded library %s for %s", lib, cls);
6101 }
6102 status = 1;
6103 }
6104 else {
6105 gCling->Error("TCling::AutoLoad",
6106 "failure loading library %s for %s", lib, cls);
6107 }
6108 }
6109 delete tokens;
6110 }
6111
6112 return status;
6113}
6114
6115////////////////////////////////////////////////////////////////////////////////
6116// Iterate through the data member of the class (either through the TProtoClass
6117// or through Cling) and trigger, recursively, the loading the necessary libraries.
6118// \note `cls` is expected to be already normalized!
6119// \returns 1 on success.
6120Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6121 bool nameIsNormalized)
6122{
6123 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6124 // has previously (within the same call to `AutoLoad()`) tried to load this class
6125 // and we are done, whether success or not, as it won't work better now than before,
6126 // because there is no additional information now compared to before.
6127 if (!visited.insert(std::string(cls)).second)
6128 return 1;
6129
6130 if (ShallowAutoLoadImpl(cls) == 0) {
6131 // If ShallowAutoLoadImpl() has an error, we have an error.
6132 return 0;
6133 }
6134
6135 // Now look through the TProtoClass to load the required library/dictionary
6136 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6137 for (auto element : proto->GetData()) {
6138 if (element->IsBasic())
6139 continue;
6140 const char *subtypename = element->GetTypeName();
6141 if (!TClassTable::GetDictNorm(subtypename)) {
6142 // Failure to load a dictionary is not (quite) a failure load
6143 // the top-level library. If we return false here, then
6144 // we would end up in a situation where the library and thus
6145 // the dictionary is loaded for "cls" but the TClass is
6146 // not created and/or marked as unavailable (in case where
6147 // AutoLoad is called from TClass::GetClass).
6148 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6149 }
6150 }
6151 return 1;
6152 }
6153
6154 // We found no TProtoClass for cls.
6155 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6156 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6157 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6158 {
6159 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6160 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6161 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6162 continue;
6163 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6164 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6165 // Failure to load a dictionary is not (quite) a failure load
6166 // the top-level library. See detailed comment in the TProtoClass
6167 // branch (above).
6168 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6169 }
6170 }
6171 gInterpreter->DataMemberInfo_Delete(memberinfo);
6172 }
6173 gInterpreter->ClassInfo_Delete(classinfo);
6174 return 1;
6175}
6176
6177////////////////////////////////////////////////////////////////////////////////
6178/// Load library containing the specified class. Returns 0 in case of error
6179/// and 1 in case if success.
6180
6181Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6182{
6183 // Prevent update to IsClassAutoloading between our check and our actions.
6185
6186 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6187 // rootcling (in *_rdict.pcm file generation) it is a no op.
6188 // FIXME: We should avoid calling autoload when we know we are not supposed
6189 // to and transform this check into an assert.
6191 // Never load any library from rootcling/genreflex.
6192 if (gDebug > 2) {
6193 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6194 }
6195 return 0;
6196 }
6197
6198 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6199
6201
6202 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6203 // The library is already loaded as the class's dictionary is known.
6204 // Return success.
6205 // Note: the name (cls) is expected to be normalized as it comes either
6206 // from a callbacks (that can/should calculate the normalized name from the
6207 // decl) or from TClass::GetClass (which does also calculate the normalized
6208 // name).
6209 return 1;
6210 }
6211
6212 if (gDebug > 2) {
6213 Info("TCling::AutoLoad",
6214 "Trying to autoload for %s", cls);
6215 }
6216
6217 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6218 if (gDebug > 2) {
6219 Info("TCling::AutoLoad",
6220 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6221 }
6222 return 0;
6223 }
6224 // Prevent the recursion when the library dictionary are loaded.
6225 SuspendAutoLoadingRAII autoLoadOff(this);
6226 // Try using externally provided callback first.
6227 if (fAutoLoadCallBack) {
6228 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6229 if (success)
6230 return success;
6231 }
6232
6233 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6234 // (when module are enabled) which might end up calling AutoParsing but
6235 // that should only be for the cases where the library has no generated pcm
6236 // and in that case a rootmap should be available.
6237 // This avoids a very costly operation (for generally no gain) but reduce the
6238 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6239 // file).
6240 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6241 std::unordered_set<std::string> visited;
6242 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6243}
6244
6245////////////////////////////////////////////////////////////////////////////////
6246/// Parse the payload or header.
6247
6248static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6249 Bool_t header,
6250 cling::Interpreter *interpreter)
6251{
6252 std::string code = gNonInterpreterClassDef ;
6253 if (!header) {
6254 // This is the complete header file content and not the
6255 // name of a header.
6256 code += what;
6257
6258 } else {
6259 code += ("#include \"");
6260 code += what;
6261 code += "\"\n";
6262 }
6263 code += ("#ifdef __ROOTCLING__\n"
6264 "#undef __ROOTCLING__\n"
6265 + gInterpreterClassDef +
6266 "#endif");
6267
6268 cling::Interpreter::CompilationResult cr;
6269 {
6270 // scope within which diagnostics are de-activated
6271 // For now we disable diagnostics because we saw them already at
6272 // dictionary generation time. That won't be an issue with the PCMs.
6273
6274 Sema &SemaR = interpreter->getSema();
6275 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6276 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6277
6278 #if defined(R__MUST_REVISIT)
6279 #if R__MUST_REVISIT(6,2)
6280 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6281 #endif
6282 #endif
6283
6284 cr = interpreter->parseForModule(code);
6285 }
6286 return cr;
6287}
6288
6289////////////////////////////////////////////////////////////////////////////////
6290/// Helper routine for TCling::AutoParse implementing the actual call to the
6291/// parser and looping over template parameters (if
6292/// any) and when they don't have a registered header to autoparse,
6293/// recurse over their template parameters.
6294///
6295/// Returns the number of header parsed.
6296
6297UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6298{
6299 // We assume the lock has already been taken.
6300 // R__LOCKGUARD(gInterpreterMutex);
6301
6302 Int_t nHheadersParsed = 0;
6303 unsigned long offset = 0;
6304 if (strncmp(cls, "const ", 6) == 0) {
6305 offset = 6;
6306 }
6307
6308 // Loop on the possible autoparse keys
6309 bool skipFirstEntry = false;
6310 std::vector<std::string> autoparseKeys;
6311 if (strchr(cls, '<')) {
6312 int nestedLoc = 0;
6313 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6314 // Check if we can skip the name of the template in the autoparses
6315 // Take all the scopes one by one. If all of them are in the AST, we do not
6316 // need to autoparse for that particular template.
6317 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6318 // autoparseKeys[0] is empty when the input is not a template instance.
6319 // The case strchr(cls, '<') != 0 but still not a template instance can
6320 // happens 'just' for string (GetSplit replaces the template by the short name
6321 // and then use that for thew splitting)
6322 TString templateName(autoparseKeys[0]);
6323 auto tokens = templateName.Tokenize("::");
6324 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6325 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6326 if (TClassEdit::IsStdClass(cls + offset))
6327 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6328 auto nTokens = tokens->GetEntriesFast();
6329 for (Int_t tk = 0; tk < nTokens; ++tk) {
6330 auto scopeObj = tokens->UncheckedAt(tk);
6331 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6332 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6333 // Check if we have multiple nodes in the AST with this name
6334 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6335 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6336 if (!previousScopeAsContext) break; // this is not a context
6337 }
6338 delete tokens;
6339 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6340 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6341 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6342 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6343 skipFirstEntry = templatedDecl->hasDefinition();
6344 }
6345 }
6346 }
6347
6348 }
6349 }
6350 if (topLevel) autoparseKeys.emplace_back(cls);
6351
6352 for (const auto & apKeyStr : autoparseKeys) {
6353 if (skipFirstEntry) {
6354 skipFirstEntry=false;
6355 continue;
6356 }
6357 if (apKeyStr.empty()) continue;
6358 const char *apKey = apKeyStr.c_str();
6359 std::size_t normNameHash(fStringHashFunction(apKey));
6360 // If the class was not looked up
6361 if (gDebug > 1) {
6362 Info("TCling::AutoParse",
6363 "Starting autoparse for %s\n", apKey);
6364 }
6365 if (fLookedUpClasses.insert(normNameHash).second) {
6366 auto const &iter = fClassesHeadersMap.find(normNameHash);
6367 if (iter != fClassesHeadersMap.end()) {
6368 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6369 fTransactionHeadersMap.insert({T,normNameHash});
6370 auto const &hNamesPtrs = iter->second;
6371 if (gDebug > 1) {
6372 Info("TCling::AutoParse",
6373 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6374 }
6375 for (auto & hName : hNamesPtrs) {
6376 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6377 if (0 != fPayloads.count(normNameHash)) {
6378 float initRSSval=0.f, initVSIZEval=0.f;
6379 (void) initRSSval; // Avoid unused var warning
6380 (void) initVSIZEval;
6381 if (gDebug > 0) {
6382 Info("AutoParse",
6383 "Parsing full payload for %s", apKey);
6384 ProcInfo_t info;
6385 gSystem->GetProcInfo(&info);
6386 initRSSval = 1e-3*info.fMemResident;
6387 initVSIZEval = 1e-3*info.fMemVirtual;
6388 }
6389 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6390 if (cRes != cling::Interpreter::kSuccess) {
6391 if (hName[0] == '\n')
6392 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6393 } else {
6394 fParsedPayloadsAddresses.insert(hName);
6395 nHheadersParsed++;
6396 if (gDebug > 0){
6397 ProcInfo_t info;
6398 gSystem->GetProcInfo(&info);
6399 float endRSSval = 1e-3*info.fMemResident;
6400 float endVSIZEval = 1e-3*info.fMemVirtual;
6401 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6402 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6403 }
6404 }
6405 } else if (!IsLoaded(hName)) {
6406 if (gDebug > 0) {
6407 Info("AutoParse",
6408 "Parsing single header %s", hName);
6409 }
6410 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6411 if (cRes != cling::Interpreter::kSuccess) {
6412 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6413 } else {
6414 nHheadersParsed++;
6415 }
6416 }
6417 }
6418 }
6419 else {
6420 // There is no header registered for this class, if this a
6421 // template, it will be instantiated if/when it is requested
6422 // and if we do no load/parse its components we might end up
6423 // not using an eventual specialization.
6424 if (strchr(apKey, '<')) {
6425 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6426 }
6427 }
6428 }
6429 }
6430
6431 return nHheadersParsed;
6432
6433}
6434
6435////////////////////////////////////////////////////////////////////////////////
6436/// Parse the headers relative to the class
6437/// Returns 1 in case of success, 0 in case of failure
6438
6439Int_t TCling::AutoParse(const char *cls)
6440{
6441 if (llvm::StringRef(cls).contains("(lambda)"))
6442 return 0;
6443
6446 return AutoLoad(cls);
6447 } else {
6448 return 0;
6449 }
6450 }
6451
6453
6454 if (gDebug > 1) {
6455 Info("TCling::AutoParse",
6456 "Trying to autoparse for %s", cls);
6457 }
6458
6459 // The catalogue of headers is in the dictionary
6461 && !gClassTable->GetDictNorm(cls)) {
6462 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6463 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6464 fInterpreter->getSema());
6465 AutoLoad(cls, true /*knowDictNotLoaded*/);
6466 }
6467
6468 // Prevent the recursion when the library dictionary are loaded.
6469 SuspendAutoLoadingRAII autoLoadOff(this);
6470
6471 // No recursive header parsing on demand; we require headers to be standalone.
6472 SuspendAutoParsing autoParseRAII(this);
6473
6474 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6475
6477
6478 return nHheadersParsed > 0 ? 1 : 0;
6479}
6480
6481// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6482// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6483// false if not.
6484bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6485{
6486 StringRef errMsg(errmessage);
6487 if (errMsg.contains("undefined symbol: ")) {
6488 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6489 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6490 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6491 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6492 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6493 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6494 return true;
6495 } else {
6496 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6497 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6498 return true;
6499 }
6500
6501 return false;
6502}
6503
6504static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
6505 const cling::DynamicLibraryManager &DLM) {
6507
6508 auto LibLoader = [](const std::string& LibName) -> bool {
6509 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6510 Error("TCling__LazyFunctionCreatorAutoloadForModule",
6511 "Failed to load library %s", LibName.c_str());
6512 return false;
6513 }
6514 return true; //success.
6515 };
6516
6517#ifdef R__MACOSX
6518 // The JIT gives us a mangled name which has only one leading underscore on
6519 // all platforms, for instance _ZN8TRandom34RndmEv. However, on OSX the
6520 // linker stores this symbol as __ZN8TRandom34RndmEv (adding an extra _).
6521 assert(!llvm::StringRef(mangled_name).startswith("__") && "Already added!");
6522 std::string libName = DLM.searchLibrariesForSymbol('_' + mangled_name,
6523 /*searchSystem=*/ true);
6524#else
6525 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6526 /*searchSystem=*/ true);
6527#endif //R__MACOSX
6528
6529 assert(!llvm::StringRef(libName).startswith("libNew") &&
6530 "We must not resolve symbols from libNew!");
6531
6532 if (libName.empty())
6533 return nullptr;
6534
6535 if (!LibLoader(libName))
6536 return nullptr;
6537
6538 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name);
6539
6540}
6541
6542////////////////////////////////////////////////////////////////////////////////
6543/// Autoload a library based on a missing symbol.
6544
6545void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6547 return LazyFunctionCreatorAutoloadForModule(mangled_name,
6548 *GetInterpreterImpl()->getDynamicLibraryManager());
6549
6550 // First see whether the symbol is in the library that we are currently
6551 // loading. It will have access to the symbols of its dependent libraries,
6552 // thus checking "back()" is sufficient.
6553 if (!fRegisterModuleDyLibs.empty()) {
6554 if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
6555 mangled_name.c_str())) {
6556 return addr;
6557 }
6558 }
6559
6560 int err = 0;
6561 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6562 if (err) {
6563 return 0;
6564 }
6565
6566 std::string name(demangled_name_c);
6567 free(demangled_name_c);
6568
6569 //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
6570 //
6571 // Separate out the class or namespace part of the
6572 // function name.
6573 //
6574
6575 std::string::size_type pos = name.find("__thiscall ");
6576 if (pos != std::string::npos) {
6577 name.erase(0, pos + sizeof("__thiscall ")-1);
6578 }
6579 pos = name.find("__cdecl ");
6580 if (pos != std::string::npos) {
6581 name.erase(0, pos + sizeof("__cdecl ")-1);
6582 }
6583 if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
6584 name.erase(0, sizeof("typeinfo for ")-1);
6585 } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
6586 name.erase(0, sizeof("vtable for ")-1);
6587 } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
6588 && !isalnum(name[sizeof("operator")])) {
6589 // operator...(A, B) - let's try with A!
6590 name.erase(0, sizeof("operator")-1);
6591 pos = name.rfind('(');
6592 if (pos != std::string::npos) {
6593 name.erase(0, pos + 1);
6594 pos = name.find(",");
6595 if (pos != std::string::npos) {
6596 // remove next arg up to end, leaving only the first argument type.
6597 name.erase(pos);
6598 }
6599 pos = name.rfind(" const");
6600 if (pos != std::string::npos) {
6601 name.erase(pos, strlen(" const"));
6602 }
6603 while (!name.empty() && strchr("&*", name.back()))
6604 name.erase(name.length() - 1);
6605 }
6606 } else {
6609 name = fsi.fScopeName;
6610 }
6611 //fprintf(stderr, "name: '%s'\n", name.c_str());
6612 // Now we have the class or namespace name, so do the lookup.
6613 TString libs = GetClassSharedLibs(name.c_str());
6614 if (libs.IsNull()) {
6615 // Not found in the map, all done.
6616 return 0;
6617 }
6618 //fprintf(stderr, "library: %s\n", iter->second.c_str());
6619 // Now we have the name of the libraries to load, so load them.
6620
6621 TString lib;
6622 Ssiz_t posLib = 0;
6623 while (libs.Tokenize(lib, posLib)) {
6624 if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
6625 // The library load failed, all done.
6626 //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
6627 return 0;
6628 }
6629 }
6630
6631 //fprintf(stderr, "load succeeded.\n");
6632 // Get the address of the function being called.
6633 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6634 //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
6635 return addr;
6636}
6637
6638////////////////////////////////////////////////////////////////////////////////
6639
6640Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6641{
6642 return fNSFromRootmaps.count(nsDecl) != 0;
6643}
6644
6645////////////////////////////////////////////////////////////////////////////////
6646/// Internal function. Actually do the update of the ClassInfo when seeing
6647// new TagDecl or NamespaceDecl.
6648void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6649{
6650
6652 if (cci) {
6653 // If we only had a forward declaration then update the
6654 // TClingClassInfo with the definition if we have it now.
6655 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6656 if (!oldDef || (def && def != oldDef)) {
6657 cl->ResetCaches();
6659 if (def) {
6660 // It's a tag decl, not a namespace decl.
6661 cci->Init(*cci->GetType());
6663 }
6664 }
6665 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6666 cl->ResetCaches();
6667 // yes, this is almost a waste of time, but we do need to lookup
6668 // the 'type' corresponding to the TClass anyway in order to
6669 // preserve the opaque typedefs (Double32_t)
6670 if (!alias && def != nullptr)
6671 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6672 else
6673 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6674 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6675 // We now need to update the state and bits.
6676 if (cl->fState != TClass::kHasTClassInit) {
6677 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6680 }
6681 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6682 } else {
6683 delete ((TClingClassInfo *)cl->fClassInfo);
6684 cl->fClassInfo = nullptr;
6685 }
6686 }
6687}
6688
6689////////////////////////////////////////////////////////////////////////////////
6690/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6691void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6692{
6693 const TagDecl *td = dyn_cast<TagDecl>(ND);
6694 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6695 const NamedDecl *canon = nullptr;
6696
6697 std::string name;
6698 TagDecl* tdDef = 0;
6699 if (td) {
6700 canon = tdDef = td->getDefinition();
6701 // Let's pass the decl to the TClass only if it has a definition.
6702 if (!tdDef) return;
6703
6704 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6705 // Ignore incomplete definition.
6706 // Ignore declaration within a function.
6707 return;
6708 }
6709
6710 auto declName = tdDef->getNameAsString();
6711 // Check if we have registered the unqualified name into the list
6712 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6713 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6714 // the unqualified name is sufficient (and the fully qualified name might be
6715 // 'wrong' if there is difference in spelling in the template paramters (for example)
6716 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6717 // 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() );
6718 return;
6719 }
6720
6721 clang::QualType type(tdDef->getTypeForDecl(), 0);
6723 } else if (ns) {
6724 canon = ns->getCanonicalDecl();
6725 name = ND->getQualifiedNameAsString();
6726 } else {
6727 name = ND->getQualifiedNameAsString();
6728 }
6729
6730 // Supposedly we are being called while something is being
6731 // loaded ... let's now tell the autoloader to do the work
6732 // yet another time.
6733 SuspendAutoLoadingRAII autoLoadOff(this);
6734 // FIXME: There can be more than one TClass for a single decl.
6735 // for example vector<double> and vector<Double32_t>
6736 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6737 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6738 RefreshClassInfo(cl, canon, false);
6739 }
6740 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6741 // and update them too:
6742 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6743 // RefreshClassInfo(cl, tdDef, true);
6744}
6745
6746////////////////////////////////////////////////////////////////////////////////
6747/// No op: see TClingCallbacks
6748
6749void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6750{
6751}
6752
6753//______________________________________________________________________________
6754//FIXME: Factor out that function in TClass, because TClass does it already twice
6755void TCling::UpdateClassInfoWork(const char* item)
6756{
6757 // This is a no-op as part of the API.
6758 // TCling uses UpdateClassInfoWithDecl() instead.
6759}
6760
6761////////////////////////////////////////////////////////////////////////////////
6762/// Update all canvases at end the terminal input command.
6763
6765{
6766 TIter next(gROOT->GetListOfCanvases());
6767 TVirtualPad* canvas;
6768 while ((canvas = (TVirtualPad*)next())) {
6769 canvas->Update();
6770 }
6771}
6772
6773////////////////////////////////////////////////////////////////////////////////
6774
6775void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6776 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6777
6778 // If the transaction does not contain anything we can return earlier.
6779 if (!HandleNewTransaction(T)) return;
6780
6781 bool isTUTransaction = false;
6782 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6783 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6784 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6785 // The is the first transaction, we have to expose to meta
6786 // what's already in the AST.
6787 isTUTransaction = true;
6788 }
6789 }
6790
6791 std::set<const void*> TransactionDeclSet;
6792 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6793 const clang::Decl* WrapperFD = T.getWrapperFD();
6794 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6795 I != E; ++I) {
6796 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6797 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6798 continue;
6799
6800 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6801 DE = I->m_DGR.end(); DI != DE; ++DI) {
6802 if (*DI == WrapperFD)
6803 continue;
6804 TransactionDeclSet.insert(*DI);
6805 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6806 }
6807 }
6808 }
6809
6810 // The above might trigger more decls to be deserialized.
6811 // Thus the iteration over the deserialized decls must be last.
6812 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6813 E = T.deserialized_decls_end(); I != E; ++I) {
6814 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6815 DE = I->m_DGR.end(); DI != DE; ++DI)
6816 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6817 //FIXME: HandleNewDecl should take DeclGroupRef
6818 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6819 modifiedTClasses);
6820 }
6821 }
6822
6823
6824 // When fully building the reflection info in TClass, a deserialization
6825 // could be triggered, which may result in request for building the
6826 // reflection info for the same TClass. This in turn will clear the caches
6827 // for the TClass in-flight and cause null ptr derefs.
6828 // FIXME: This is a quick fix, solving most of the issues. The actual
6829 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6830 // itself until the update is done.
6831 //
6832 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6833 std::vector<TClass*>::iterator it;
6834 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6835 ((TCling*)gCling)->GetModTClasses().begin(),
6836 ((TCling*)gCling)->GetModTClasses().end(),
6837 modifiedTClassesDiff.begin());
6838 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6839
6840 // Lock the TClass for updates
6841 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6842 modifiedTClassesDiff.end());
6843 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6844 E = modifiedTClassesDiff.end(); I != E; ++I) {
6845 // Make sure the TClass has not been deleted.
6846 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6847 continue;
6848 }
6849 // Could trigger deserialization of decls.
6850 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6851 // Unlock the TClass for updates
6852 ((TCling*)gCling)->GetModTClasses().erase(*I);
6853
6854 }
6855}
6856
6857///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6858///
6859void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6860{
6862
6863 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6864 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6865 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6866 (TListOfEnums *)gROOT->GetListOfEnums());
6867
6868 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6869 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6870 I != E; ++I) {
6871 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6872 continue;
6873 if (I->m_Call == cling::Transaction::kCCINone) {
6874 UpdateListsOnUnloaded(*(*iNested));
6875 ++iNested;
6876 continue;
6877 }
6878
6879 for (auto &D : I->m_DGR)
6880 InvalidateCachedDecl(Lists, D);
6881 }
6882}
6883
6884///\brief Invalidate cached TCling information for the given global declaration.
6885///
6886void TCling::InvalidateGlobal(const Decl *D) {
6887 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6888 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6889 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6890 (TListOfEnums *)gROOT->GetListOfEnums());
6891 InvalidateCachedDecl(Lists, D);
6892}
6893
6894///\brief Invalidate cached TCling information for the given declaration, and
6895/// removed it from the appropriate object list.
6896///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6897/// TListOfFunctionTemplates&, TListOfEnums&>
6898/// of pointers to the (global/class) object lists.
6899///\param[in] D - Decl to discard.
6900///
6904 TListOfEnums*> &Lists, const Decl *D) {
6905 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6906 return;
6907
6908 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6909 TListOfFunctions &LOF = *(std::get<1>(Lists));
6910 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6911 TListOfEnums &LOE = *(std::get<3>(Lists));
6912
6913 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6914 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6915 if (LODM.GetClass())
6916 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6917 else
6918 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6919 } else if (isa<FunctionDecl>(D)) {
6921 } else if (isa<FunctionTemplateDecl>(D)) {
6923 } else if (isa<EnumDecl>(D)) {
6924 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6925 if (!E)
6926 return;
6927
6928 // Try to invalidate enumerators (for unscoped enumerations).
6929 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6931 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6932
6934 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6935 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6936 return;
6937
6938 std::vector<TClass *> Classes;
6939 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6940 return;
6941 for (auto &C : Classes) {
6942 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6943 (TListOfFunctions *)C->GetListOfMethods(),
6944 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6945 (TListOfEnums *)C->GetListOfEnums());
6946 for (auto &I : cast<DeclContext>(D)->decls())
6947 InvalidateCachedDecl(Lists, I);
6948
6949 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6950 if (D->getKind() != Decl::Namespace
6951 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6952 C->ResetClassInfo();
6953 }
6954 }
6955}
6956
6957////////////////////////////////////////////////////////////////////////////////
6958// If an autoparse was done during a transaction and that it is rolled back,
6959// we need to make sure the next request for the same autoparse will be
6960// honored.
6961void TCling::TransactionRollback(const cling::Transaction &T) {
6962 auto const &triter = fTransactionHeadersMap.find(&T);
6963 if (triter != fTransactionHeadersMap.end()) {
6964 std::size_t normNameHash = triter->second;
6965
6966 fLookedUpClasses.erase(normNameHash);
6967
6968 auto const &iter = fClassesHeadersMap.find(normNameHash);
6969 if (iter != fClassesHeadersMap.end()) {
6970 auto const &hNamesPtrs = iter->second;
6971 for (auto &hName : hNamesPtrs) {
6972 if (gDebug > 0) {
6973 Info("TransactionRollback",
6974 "Restoring ability to autoaparse: %s", hName);
6975 }
6976 fParsedPayloadsAddresses.erase(hName);
6977 }
6978 }
6979 }
6980}
6981
6982////////////////////////////////////////////////////////////////////////////////
6983
6984void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6985// R__LOCKGUARD_CLING(gInterpreterMutex);
6986// UpdateListOfLoadedSharedLibraries();
6987}
6988
6989////////////////////////////////////////////////////////////////////////////////
6990
6991void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6993 fSharedLibs = "";
6994}
6995
6996////////////////////////////////////////////////////////////////////////////////
6997/// Return the list of shared libraries loaded into the process.
6998
7000{
7003 return fSharedLibs;
7004}
7005
7006static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
7007{
7008 if (!cls || !*cls)
7009 return {};
7010
7011 using namespace clang;
7012 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7013 /*type*/ nullptr, /*instantiate*/ false)) {
7014 if (!D->isFromASTFile()) {
7015 if (gDebug > 5)
7016 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7017 return {};
7018 }
7019 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7020 llvm::DenseSet<Module *> &m_TopLevelModules;
7021
7022 public:
7023 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7024 void Collect(const Decl *D) { Visit(D); }
7025
7026 void VisitDecl(const Decl *D)
7027 {
7028 // FIXME: Such case is described ROOT-7765 where
7029 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7030 // They are specified as #includes in the LinkDef file. This leads to
7031 // generation of incomplete modulemap files and this logic fails to
7032 // compute the corresponding module of D.
7033 // FIXME: If we want to support such a case, we should not rely on
7034 // the contents of the modulemap but mangle D and look it up in the
7035 // .so files.
7036 if (!D->hasOwningModule())
7037 return;
7038 if (Module *M = D->getOwningModule()->getTopLevelModule())
7039 m_TopLevelModules.insert(M);
7040 }
7041
7042 void VisitTemplateArgument(const TemplateArgument &TA)
7043 {
7044 switch (TA.getKind()) {
7045 case TemplateArgument::Null:
7046 case TemplateArgument::Integral:
7047 case TemplateArgument::Pack:
7048 case TemplateArgument::NullPtr:
7049 case TemplateArgument::Expression:
7050 case TemplateArgument::Template:
7051 case TemplateArgument::TemplateExpansion: return;
7052 case TemplateArgument::Type:
7053 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7054 return Visit(TagTy->getDecl());
7055 return;
7056 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7057 }
7058 llvm_unreachable("Invalid TemplateArgument::Kind!");
7059 }
7060
7061 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7062 {
7063 if (CTSD->getOwningModule())
7064 VisitDecl(CTSD);
7065 else
7066 VisitDecl(CTSD->getSpecializedTemplate());
7067 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7068 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7069 VisitTemplateArgument(*Arg);
7070 }
7071 }
7072 };
7073
7074 llvm::DenseSet<Module *> TopLevelModules;
7075 ModuleCollector m(TopLevelModules);
7076 m.Collect(D);
7077 std::string result;
7078 for (auto M : TopLevelModules) {
7079 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7080 // link declaration.
7081 if (!M->LinkLibraries.size())
7082 continue;
7083 // We have preloaded the Core module thus libCore.so
7084 if (M->Name == "Core")
7085 continue;
7086 assert(M->LinkLibraries.size() == 1);
7087 if (!result.empty())
7088 result += ' ';
7089 result += M->LinkLibraries[0].Library;
7090 }
7091 return result;
7092 }
7093 return {};
7094}
7095
7096////////////////////////////////////////////////////////////////////////////////
7097/// Get the list of shared libraries containing the code for class cls.
7098/// The first library in the list is the one containing the class, the
7099/// others are the libraries the first one depends on. Returns 0
7100/// in case the library is not found.
7101
7102const char* TCling::GetClassSharedLibs(const char* cls)
7103{
7104 if (fCxxModulesEnabled) {
7105 llvm::StringRef className = cls;
7106 // If we get a class name containing lambda, we cannot parse it and we
7107 // can exit early.
7108 // FIXME: This works around a bug when we are instantiating a template
7109 // make_unique and the substitution fails. Seen in most of the dataframe
7110 // tests.
7111 if (className.contains("(lambda)"))
7112 return nullptr;
7113 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7114 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7115 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7116 std::string libs = GetClassSharedLibsForModule(cls, LH);
7117 if (!libs.empty()) {
7118 fAutoLoadLibStorage.push_back(libs);
7119 return fAutoLoadLibStorage.back().c_str();
7120 }
7121 }
7122
7123 if (!cls || !*cls) {
7124 return 0;
7125 }
7126 // lookup class to find list of libraries
7127 if (fMapfile) {
7128 TEnvRec* libs_record = 0;
7129 libs_record = fMapfile->Lookup(cls);
7130 if (libs_record) {
7131 const char* libs = libs_record->GetValue();
7132 return (*libs) ? libs : 0;
7133 }
7134 else {
7135 // Try the old format...
7136 TString c = TString("Library.") + cls;
7137 // convert "::" to "@@", we used "@@" because TEnv
7138 // considers "::" a terminator
7139 c.ReplaceAll("::", "@@");
7140 // convert "-" to " ", since class names may have
7141 // blanks and TEnv considers a blank a terminator
7142 c.ReplaceAll(" ", "-");
7143 // Use TEnv::Lookup here as the rootmap file must start with Library.
7144 // and do not support using any stars (so we do not need to waste time
7145 // with the search made by TEnv::GetValue).
7146 TEnvRec* libs_record = 0;
7147 libs_record = fMapfile->Lookup(c);
7148 if (libs_record) {
7149 const char* libs = libs_record->GetValue();
7150 return (*libs) ? libs : 0;
7151 }
7152 }
7153 }
7154 return 0;
7155}
7156
7157/// This interface returns a list of dependent libraries in the form:
7158/// lib libA.so libB.so libC.so. The first library is the library we are
7159/// searching dependencies for.
7160/// Note: In order to speed up the search, we display the dependencies of the
7161/// libraries which are not yet loaded. For instance, if libB.so was already
7162/// loaded the list would contain: lib libA.so libC.so.
7163static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7164 cling::Interpreter *interp,
7165 bool skipLoadedLibs = true)
7166{
7167 TString LibFullPath(lib);
7168 if (!llvm::sys::path::is_absolute(lib)) {
7169 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7170 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7171 return "";
7172 }
7173 } else {
7174 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7175 lib = llvm::sys::path::filename(lib);
7176 }
7177
7178 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7179 if (!ObjF) {
7180 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7181 return "";
7182 }
7183
7184 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7185
7186 std::set<string> DedupSet;
7187 std::string Result = lib + ' ';
7188 for (const auto &S : BinObjFile->symbols()) {
7189 uint32_t Flags = S.getFlags();
7190 if (Flags & llvm::object::SymbolRef::SF_Undefined) {
7191 llvm::Expected<StringRef> SymNameErr = S.getName();
7192 if (!SymNameErr) {
7193 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7194 continue;
7195 }
7196 llvm::StringRef SymName = SymNameErr.get();
7197 if (SymName.empty())
7198 continue;
7199
7200 if (BinObjFile->isELF()) {
7201 // Skip the symbols which are part of the C/C++ runtime and have a
7202 // fixed library version. See binutils ld VERSION. Those reside in
7203 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7204 if (SymName.contains("@@GLIBCXX") || SymName.contains("@@CXXABI") ||
7205 SymName.contains("@@GLIBC") || SymName.contains("@@GCC"))
7206 continue;
7207
7208 // Those are 'weak undefined' symbols produced by gcc. We can
7209 // ignore them.
7210 // FIXME: It is unclear whether we can ignore all weak undefined
7211 // symbols:
7212 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7213 if (SymName == "_Jv_RegisterClasses" ||
7214 SymName == "_ITM_deregisterTMCloneTable" ||
7215 SymName == "_ITM_registerTMCloneTable")
7216 continue;
7217 }
7218
7219// FIXME: this might really depend on MachO library format instead of R__MACOSX.
7220#ifdef R__MACOSX
7221 // MacOS symbols sometimes have an extra "_", see
7222 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
7223 if (skipLoadedLibs && SymName[0] == '_'
7224 && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName.drop_front()))
7225 continue;
7226#endif
7227
7228 // If we can find the address of the symbol, we have loaded it. Skip.
7229 if (skipLoadedLibs && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName))
7230 continue;
7231
7233 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7234 // The expected output is just filename without the full path, which
7235 // is not very accurate, because our Dyld implementation might find
7236 // a match in location a/b/c.so and if we return just c.so ROOT might
7237 // resolve it to y/z/c.so and there we might not be ABI compatible.
7238 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7239 if (!found.empty()) {
7240 std::string cand = llvm::sys::path::filename(found).str();
7241 if (!DedupSet.insert(cand).second)
7242 continue;
7243
7244 Result += cand + ' ';
7245 }
7246 }
7247 }
7248
7249 return Result;
7250}
7251
7252static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7253{
7254 // Check if we have parsed a rootmap file.
7255 llvm::SmallString<256> rootmapName;
7256 if (!lib.startswith("lib"))
7257 rootmapName.append("lib");
7258
7259 rootmapName.append(llvm::sys::path::filename(lib));
7260 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7261
7262 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7263 return true;
7264
7265 // Perform a last resort by dropping the lib prefix.
7266 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7267 if (rootmapNameNoLib.consume_front("lib"))
7268 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7269
7270 return false;
7271}
7272
7273static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7274{
7275 if (gCling->HasPCMForLibrary(lib.data()))
7276 return true;
7277
7278 return hasParsedRootmapForLibrary(lib);
7279}
7280
7281////////////////////////////////////////////////////////////////////////////////
7282/// Get the list a libraries on which the specified lib depends. The
7283/// returned string contains as first element the lib itself.
7284/// Returns 0 in case the lib does not exist or does not have
7285/// any dependencies. If useDyld is true, we iterate through all available
7286/// libraries and try to construct the dependency chain by resolving each
7287/// symbol.
7288
7289const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7290{
7291 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7292 return nullptr;
7293
7294 if (!hasParsedRootmapForLibrary(lib)) {
7295 llvm::SmallString<512> rootmapName(lib);
7296 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7297 if (llvm::sys::fs::exists(rootmapName)) {
7298 if (gDebug > 0)
7299 Info("Load", "loading %s", rootmapName.c_str());
7300 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7301 }
7302 }
7303
7304 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7305 if (gDebug > 0)
7306 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7307 }
7308
7309 if (useDyld) {
7310 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7311 if (!libs.empty()) {
7312 fAutoLoadLibStorage.push_back(libs);
7313 return fAutoLoadLibStorage.back().c_str();
7314 }
7315 }
7316
7317 if (!fMapfile || !lib || !lib[0]) {
7318 return 0;
7319 }
7320 TString libname(lib);
7321 Ssiz_t idx = libname.Last('.');
7322 if (idx != kNPOS) {
7323 libname.Remove(idx);
7324 }
7325 TEnvRec* rec;
7326 TIter next(fMapfile->GetTable());
7327 size_t len = libname.Length();
7328 while ((rec = (TEnvRec*) next())) {
7329 const char* libs = rec->GetValue();
7330 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7331 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7332 return libs;
7333 }
7334 }
7335 return 0;
7336}
7337
7338////////////////////////////////////////////////////////////////////////////////
7339/// If error messages are disabled, the interpreter should suppress its
7340/// failures and warning messages from stdout.
7341
7343{
7344#if defined(R__MUST_REVISIT)
7345#if R__MUST_REVISIT(6,2)
7346 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7347#endif
7348#endif
7349 return kTRUE;
7350}
7351
7352////////////////////////////////////////////////////////////////////////////////
7353/// If error messages are disabled, the interpreter should suppress its
7354/// failures and warning messages from stdout. Return the previous state.
7355
7357{
7358#if defined(R__MUST_REVISIT)
7359#if R__MUST_REVISIT(6,2)
7360 Warning("SetErrorMessages", "Interface not available yet.");
7361#endif
7362#endif
7364}
7365
7366////////////////////////////////////////////////////////////////////////////////
7367/// Refresh the list of include paths known to the interpreter and return it
7368/// with -I prepended.
7369
7371{
7373
7374 fIncludePath = "";
7375
7376 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7377 //false - no system header, true - with flags.
7378 fInterpreter->GetIncludePaths(includePaths, false, true);
7379 if (const size_t nPaths = includePaths.size()) {
7380 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7381
7382 for (size_t i = 0; i < nPaths; i += 2) {
7383 if (i)
7384 fIncludePath.Append(' ');
7385 fIncludePath.Append(includePaths[i].c_str());
7386
7387 if (includePaths[i] != "-I")
7388 fIncludePath.Append(' ');
7389 fIncludePath.Append('"');
7390 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7391 fIncludePath.Append('"');
7392 }
7393 }
7394
7395 return fIncludePath;
7396}
7397
7398////////////////////////////////////////////////////////////////////////////////
7399/// Return the directory containing CINT's stl cintdlls.
7400
7401const char* TCling::GetSTLIncludePath() const
7402{
7403 return "";
7404}
7405
7406//______________________________________________________________________________
7407// M I S C
7408//______________________________________________________________________________
7409
7410int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7411{
7412 // Interface to cling function
7413 return 0;
7414}
7415
7416////////////////////////////////////////////////////////////////////////////////
7417/// Interface to cling function
7418
7419int TCling::DisplayIncludePath(FILE *fout) const
7420{
7421 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
7422
7423 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7424 //false - no system header, true - with flags.
7425 fInterpreter->GetIncludePaths(includePaths, false, true);
7426 if (const size_t nPaths = includePaths.size()) {
7427 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7428
7429 std::string allIncludes("include path:");
7430 for (size_t i = 0; i < nPaths; i += 2) {
7431 allIncludes += ' ';
7432 allIncludes += includePaths[i];
7433
7434 if (includePaths[i] != "-I")
7435 allIncludes += ' ';
7436 allIncludes += includePaths[i + 1];
7437 }
7438
7439 fprintf(fout, "%s\n", allIncludes.c_str());
7440 }
7441
7442 return 0;
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446/// Interface to cling function
7447
7448void* TCling::FindSym(const char* entry) const
7449{
7450 return fInterpreter->getAddressOfGlobal(entry);
7451}
7452
7453////////////////////////////////////////////////////////////////////////////////
7454/// Let the interpreter issue a generic error, and set its error state.
7455
7456void TCling::GenericError(const char* error) const
7457{
7458#if defined(R__MUST_REVISIT)
7459#if R__MUST_REVISIT(6,2)
7460 Warning("GenericError","Interface not available yet.");
7461#endif
7462#endif
7463}
7464
7465////////////////////////////////////////////////////////////////////////////////
7466/// This routines used to return the address of the internal wrapper
7467/// function (of the interpreter) that was used to call *all* the
7468/// interpreted functions that were bytecode compiled (no longer
7469/// interpreted line by line). In Cling, there is no such
7470/// wrapper function.
7471/// In practice this routines was use to decipher whether the
7472/// pointer returns by InterfaceMethod could be used to uniquely
7473/// represent the function. In Cling if the function is in a
7474/// useable state (its compiled version is available), this is
7475/// always the case.
7476/// See TClass::GetMethod.
7477
7479{
7480 return 0;
7481}
7482
7483////////////////////////////////////////////////////////////////////////////////
7484/// Interface to cling function
7485
7487{
7488#if defined(R__MUST_REVISIT)
7489#if R__MUST_REVISIT(6,2)
7490 Warning("GetSecurityError", "Interface not available yet.");
7491#endif
7492#endif
7493 return 0;
7494}
7495
7496////////////////////////////////////////////////////////////////////////////////
7497/// Load a source file or library called path into the interpreter.
7498
7499int TCling::LoadFile(const char* path) const
7500{
7501 cling::Interpreter::CompilationResult compRes;
7502 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7503 return compRes == cling::Interpreter::kFailure;
7504}
7505
7506////////////////////////////////////////////////////////////////////////////////
7507/// Load the declarations from text into the interpreter.
7508/// Note that this cannot be (top level) statements; text must contain
7509/// top level declarations.
7510/// Returns true on success, false on failure.
7511
7512Bool_t TCling::LoadText(const char* text) const
7513{
7514 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7515}
7516
7517////////////////////////////////////////////////////////////////////////////////
7518/// Interface to cling function
7519
7520const char* TCling::MapCppName(const char* name) const
7521{
7522 TTHREAD_TLS_DECL(std::string,buffer);
7524 return buffer.c_str(); // NOLINT
7525}
7526
7527////////////////////////////////////////////////////////////////////////////////
7528/// [Place holder for Mutex Lock]
7529/// Provide the interpreter with a way to
7530/// acquire a lock used to protect critical section
7531/// of its code (non-thread safe parts).
7532
7533void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7534{
7535 // nothing to do for now.
7536}
7537
7538////////////////////////////////////////////////////////////////////////////////
7539/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7540/// release a lock used to protect critical section
7541/// of its code (non-thread safe parts).
7542
7543void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7544{
7545 // nothing to do for now.
7546}
7547
7548////////////////////////////////////////////////////////////////////////////////
7549/// Returns if class AutoLoading is currently enabled.
7550
7552{
7553 if (IsFromRootCling())
7554 return false;
7555 if (!fClingCallbacks)
7556 return false;
7558}
7559
7560////////////////////////////////////////////////////////////////////////////////
7561/// Enable/Disable the AutoLoading of libraries.
7562/// Returns the old value, i.e whether it was enabled or not.
7563
7564int TCling::SetClassAutoLoading(int autoload) const
7565{
7566 // If no state change is required, exit early.
7567 // FIXME: In future we probably want to complain if we made a request which
7568 // was with the same state as before in order to catch programming errors.
7569 if ((bool) autoload == IsClassAutoLoadingEnabled())
7570 return autoload;
7571
7572 assert(fClingCallbacks && "We must have callbacks!");
7573 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7575 return oldVal;
7576}
7577
7578////////////////////////////////////////////////////////////////////////////////
7579/// Enable/Disable the Autoparsing of headers.
7580/// Returns the old value, i.e whether it was enabled or not.
7581
7583{
7584 bool oldVal = fHeaderParsingOnDemand;
7585 fHeaderParsingOnDemand = autoparse;
7586 return oldVal;
7587}
7588
7589////////////////////////////////////////////////////////////////////////////////
7590/// Suspend the Autoparsing of headers.
7591/// Returns the old value, i.e whether it was suspended or not.
7592
7597 return old;
7598}
7599
7600////////////////////////////////////////////////////////////////////////////////
7601/// Set a callback to receive error messages.
7602
7603void TCling::SetErrmsgcallback(void* p) const
7604{
7605#if defined(R__MUST_REVISIT)
7606#if R__MUST_REVISIT(6,2)
7607 Warning("SetErrmsgcallback", "Interface not available yet.");
7608#endif
7609#endif
7610}
7611
7613{
7614 if (enable) {
7615 auto consumer = new TClingDelegateDiagnosticPrinter(
7616 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7617 fInterpreter->getCI()->getLangOpts(),
7618 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7619 if (Level == clang::DiagnosticsEngine::Warning) {
7620 ::Warning("cling", "%s", Info.c_str());
7621 } else if (Level == clang::DiagnosticsEngine::Error
7622 || Level == clang::DiagnosticsEngine::Fatal) {
7623 ::Error("cling", "%s", Info.c_str());
7624 } else {
7625 ::Info("cling", "%s", Info.c_str());
7626 }
7627 });
7628 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7629 } else {
7630 fInterpreter->replaceDiagnosticConsumer(nullptr);
7631 }
7632}
7633
7634
7635////////////////////////////////////////////////////////////////////////////////
7636/// Create / close a scope for temporaries. No-op for cling; use
7637/// cling::Value instead.
7638
7639void TCling::SetTempLevel(int val) const
7640{
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644
7645int TCling::UnloadFile(const char* path) const
7646{
7647 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7648 std::string canonical = DLM->lookupLibrary(path);
7649 if (canonical.empty()) {
7650 canonical = path;
7651 }
7652 // Unload a shared library or a source file.
7653 cling::Interpreter::CompilationResult compRes;
7654 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7655 return compRes == cling::Interpreter::kFailure;
7656}
7657
7658std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7659 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7660}
7661
7662////////////////////////////////////////////////////////////////////////////////
7663/// The call to Cling's tab complition.
7664
7665void TCling::CodeComplete(const std::string& line, size_t& cursor,
7666 std::vector<std::string>& completions)
7667{
7668 fInterpreter->codeComplete(line, cursor, completions);
7669}
7670
7671////////////////////////////////////////////////////////////////////////////////
7672/// Get the interpreter value corresponding to the statement.
7673int TCling::Evaluate(const char* code, TInterpreterValue& value)
7674{
7675 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7676 auto compRes = fInterpreter->evaluate(code, *V);
7677 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7678}
7679
7680////////////////////////////////////////////////////////////////////////////////
7681
7683{
7684 using namespace cling;
7685 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7687}
7688
7689////////////////////////////////////////////////////////////////////////////////
7690/// Register value as a temporary, extending its lifetime to that of the
7691/// interpreter. This is needed for TCling's compatibility interfaces
7692/// returning long - the address of the temporary objects.
7693/// As such, "simple" types don't need to be stored; they are returned by
7694/// value; only pointers / references / objects need to be stored.
7695
7696void TCling::RegisterTemporary(const cling::Value& value)
7697{
7698 if (value.isValid() && value.needsManagedAllocation()) {
7700 fTemporaries->push_back(value);
7701 }
7702}
7703
7704////////////////////////////////////////////////////////////////////////////////
7705/// If the interpreter encounters Name, check whether that is an object ROOT
7706/// could retrieve. To not re-read objects from disk, cache the name/object
7707/// pair for a given LookupCtx.
7708
7709TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7710{
7711 // The call to FindSpecialObject might induces any kind of use
7712 // of the interpreter ... (library loading, function calling, etc.)
7713 // ... and we _know_ we are in the middle of parsing, so let's make
7714 // sure to save the state and then restore it.
7715
7716 if (gDirectory) {
7717 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7718 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7719 auto iSpecObj = iSpecObjMap->second.find(Name);
7720 if (iSpecObj != iSpecObjMap->second.end()) {
7721 LookupCtx = gDirectory;
7722 return iSpecObj->second;
7723 }
7724 }
7725 }
7726
7727 // Save state of the PP
7728 Sema &SemaR = fInterpreter->getSema();
7729 ASTContext& C = SemaR.getASTContext();
7730 Preprocessor &PP = SemaR.getPreprocessor();
7731 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7732 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7733 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7734 // After we have saved the token reset the current one to something which
7735 // is safe (semi colon usually means empty decl)
7736 Token& Tok = const_cast<Token&>(P.getCurToken());
7737 Tok.setKind(tok::semi);
7738
7739 // We can't PushDeclContext, because we go up and the routine that pops
7740 // the DeclContext assumes that we drill down always.
7741 // We have to be on the global context. At that point we are in a
7742 // wrapper function so the parent context must be the global.
7743 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7744 SemaR.TUScope);
7745
7746 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7747 if (specObj) {
7748 if (!LookupCtx) {
7749 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7750 } else {
7751 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7752 }
7753 }
7754 return specObj;
7755}
7756
7757////////////////////////////////////////////////////////////////////////////////
7758/// Inject function as a friend into klass.
7759/// With function being f in void f() {new N::PrivKlass(); } this enables
7760/// I/O of non-public classes.
7761
7762void TCling::AddFriendToClass(clang::FunctionDecl* function,
7763 clang::CXXRecordDecl* klass) const
7764{
7765 using namespace clang;
7766 ASTContext& Ctx = klass->getASTContext();
7767 FriendDecl::FriendUnion friendUnion(function);
7768 // one dummy object for the source location
7769 SourceLocation sl;
7770 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7771 klass->pushFriendDecl(friendDecl);
7772}
7773
7774//______________________________________________________________________________
7775//
7776// DeclId getter.
7777//
7778
7779////////////////////////////////////////////////////////////////////////////////
7780/// Return a unique identifier of the declaration represented by the
7781/// CallFunc
7782
7784{
7785 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7786 return 0;
7787}
7788
7789////////////////////////////////////////////////////////////////////////////////
7790/// Return a (almost) unique identifier of the declaration represented by the
7791/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7792/// when the underlying class is a template instance involving one of the
7793/// opaque typedef.
7794
7796{
7797 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7798 return 0;
7799}
7800
7801////////////////////////////////////////////////////////////////////////////////
7802/// Return a unique identifier of the declaration represented by the
7803/// MethodInfo
7804
7805TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7806{
7807 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7808 return 0;
7809}
7810
7811////////////////////////////////////////////////////////////////////////////////
7812/// Return a unique identifier of the declaration represented by the
7813/// MethodInfo
7814
7816{
7817 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7818 return 0;
7819}
7820
7821////////////////////////////////////////////////////////////////////////////////
7822/// Return a unique identifier of the declaration represented by the
7823/// TypedefInfo
7824
7826{
7827 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7828 return 0;
7829}
7830
7831//______________________________________________________________________________
7832//
7833// CallFunc interface
7834//
7835
7836////////////////////////////////////////////////////////////////////////////////
7837
7838void TCling::CallFunc_Delete(CallFunc_t* func) const
7839{
7840 delete (TClingCallFunc*) func;
7841}
7842
7843////////////////////////////////////////////////////////////////////////////////
7844
7845void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7846{
7847 TClingCallFunc* f = (TClingCallFunc*) func;
7848 f->Exec(address);
7849}
7850
7851////////////////////////////////////////////////////////////////////////////////
7852
7853void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7854{
7855 TClingCallFunc* f = (TClingCallFunc*) func;
7856 f->Exec(address, &val);
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860
7861void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7862{
7863 TClingCallFunc* f = (TClingCallFunc*) func;
7864 f->ExecWithReturn(address, ret);
7865}
7866
7867////////////////////////////////////////////////////////////////////////////////
7868
7869void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7870 const void* args[] /*=0*/,
7871 int nargs /*=0*/,
7872 void* ret/*=0*/) const
7873{
7874 TClingCallFunc* f = (TClingCallFunc*) func;
7875 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7876}
7877
7878////////////////////////////////////////////////////////////////////////////////
7879
7880Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7881{
7882 TClingCallFunc* f = (TClingCallFunc*) func;
7883 return f->ExecInt(address);
7884}
7885
7886////////////////////////////////////////////////////////////////////////////////
7887
7888Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7889{
7890 TClingCallFunc* f = (TClingCallFunc*) func;
7891 return f->ExecInt64(address);
7892}
7893
7894////////////////////////////////////////////////////////////////////////////////
7895
7896Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7897{
7898 TClingCallFunc* f = (TClingCallFunc*) func;
7899 return f->ExecDouble(address);
7900}
7901
7902////////////////////////////////////////////////////////////////////////////////
7903
7904CallFunc_t* TCling::CallFunc_Factory() const
7905{
7907 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl(), *fNormalizedCtxt);
7908}
7909
7910////////////////////////////////////////////////////////////////////////////////
7911
7912CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7913{
7914 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7915}
7916
7917////////////////////////////////////////////////////////////////////////////////
7918
7919MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7920{
7921 TClingCallFunc* f = (TClingCallFunc*) func;
7922 return (MethodInfo_t*) f->FactoryMethod();
7923}
7924
7925////////////////////////////////////////////////////////////////////////////////
7926
7927void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7928{
7929 TClingCallFunc* f = (TClingCallFunc*) func;
7930 f->IgnoreExtraArgs(ignore);
7931}
7932
7933////////////////////////////////////////////////////////////////////////////////
7934
7935void TCling::CallFunc_Init(CallFunc_t* func) const
7936{
7938 TClingCallFunc* f = (TClingCallFunc*) func;
7939 f->Init();
7940}
7941
7942////////////////////////////////////////////////////////////////////////////////
7943
7944bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7945{
7946 TClingCallFunc* f = (TClingCallFunc*) func;
7947 return f->IsValid();
7948}
7949
7950////////////////////////////////////////////////////////////////////////////////
7951
7953TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7954{
7955 TClingCallFunc* f = (TClingCallFunc*) func;
7956 return f->IFacePtr();
7957}
7958
7959////////////////////////////////////////////////////////////////////////////////
7960
7961void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7962{
7963 TClingCallFunc* f = (TClingCallFunc*) func;
7964 f->ResetArg();
7965}
7966
7967////////////////////////////////////////////////////////////////////////////////
7968
7969void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7970{
7971 TClingCallFunc* f = (TClingCallFunc*) func;
7972 f->SetArg(param);
7973}
7974
7975////////////////////////////////////////////////////////////////////////////////
7976
7977void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7978{
7979 TClingCallFunc* f = (TClingCallFunc*) func;
7980 f->SetArg(param);
7981}
7982
7983////////////////////////////////////////////////////////////////////////////////
7984
7985void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7986{
7987 TClingCallFunc* f = (TClingCallFunc*) func;
7988 f->SetArg(param);
7989}
7990
7991////////////////////////////////////////////////////////////////////////////////
7992
7993void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7994{
7995 TClingCallFunc* f = (TClingCallFunc*) func;
7996 f->SetArg(param);
7997}
7998
7999////////////////////////////////////////////////////////////////////////////////
8000
8001void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8002{
8003 TClingCallFunc* f = (TClingCallFunc*) func;
8004 f->SetArg(param);
8005}
8006
8007////////////////////////////////////////////////////////////////////////////////
8008
8009void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8010{
8011 TClingCallFunc* f = (TClingCallFunc*) func;
8012 f->SetArg(param);
8013}
8014
8015////////////////////////////////////////////////////////////////////////////////
8016
8017void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8018{
8019 TClingCallFunc* f = (TClingCallFunc*) func;
8020 f->SetArgArray(paramArr, nparam);
8021}
8022
8023////////////////////////////////////////////////////////////////////////////////
8024
8025void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8026{
8027 TClingCallFunc* f = (TClingCallFunc*) func;
8028 f->SetArgs(param);
8029}
8030
8031////////////////////////////////////////////////////////////////////////////////
8032
8033void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8034{
8035 TClingCallFunc* f = (TClingCallFunc*) func;
8036 TClingClassInfo* ci = (TClingClassInfo*) info;
8037 f->SetFunc(ci, method, params, offset);
8038}
8039
8040////////////////////////////////////////////////////////////////////////////////
8041
8042void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8043{
8044 TClingCallFunc* f = (TClingCallFunc*) func;
8045 TClingClassInfo* ci = (TClingClassInfo*) info;
8046 f->SetFunc(ci, method, params, objectIsConst, offset);
8047}
8048////////////////////////////////////////////////////////////////////////////////
8049
8050void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8051{
8052 TClingCallFunc* f = (TClingCallFunc*) func;
8053 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8054 f->SetFunc(minfo);
8055}
8056
8057////////////////////////////////////////////////////////////////////////////////
8058/// Interface to cling function
8059
8060void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8061{
8062 TClingCallFunc* f = (TClingCallFunc*) func;
8063 TClingClassInfo* ci = (TClingClassInfo*) info;
8064 f->SetFuncProto(ci, method, proto, offset, mode);
8065}
8066
8067////////////////////////////////////////////////////////////////////////////////
8068/// Interface to cling function
8069
8070void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8071{
8072 TClingCallFunc* f = (TClingCallFunc*) func;
8073 TClingClassInfo* ci = (TClingClassInfo*) info;
8074 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8075}
8076
8077////////////////////////////////////////////////////////////////////////////////
8078/// Interface to cling function
8079
8080void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8081{
8082 TClingCallFunc* f = (TClingCallFunc*) func;
8083 TClingClassInfo* ci = (TClingClassInfo*) info;
8084 llvm::SmallVector<clang::QualType, 4> funcProto;
8085 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8086 iter != end; ++iter) {
8087 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8088 }
8089 f->SetFuncProto(ci, method, funcProto, offset, mode);
8090}
8091
8092////////////////////////////////////////////////////////////////////////////////
8093/// Interface to cling function
8094
8095void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8096{
8097 TClingCallFunc* f = (TClingCallFunc*) func;
8098 TClingClassInfo* ci = (TClingClassInfo*) info;
8099 llvm::SmallVector<clang::QualType, 4> funcProto;
8100 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8101 iter != end; ++iter) {
8102 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8103 }
8104 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8105}
8106
8107std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8108{
8109 TClingCallFunc *f = (TClingCallFunc *)func;
8110 std::string wrapper_name;
8111 std::string wrapper;
8112 f->get_wrapper_code(wrapper_name, wrapper);
8113 return wrapper;
8114}
8115
8116//______________________________________________________________________________
8117//
8118// ClassInfo interface
8119//
8120
8121////////////////////////////////////////////////////////////////////////////////
8122/// Return true if the entity pointed to by 'declid' is declared in
8123/// the context described by 'info'. If info is null, look into the
8124/// global scope (translation unit scope).
8125
8126Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8127{
8128 if (!declid)
8129 return kFALSE;
8130
8131 const clang::DeclContext *ctxt = nullptr;
8132 if (info) {
8133 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8134 } else {
8135 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8136 }
8137 if (!ctxt)
8138 return kFALSE;
8139
8140 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8141 if (!decl)
8142 return kFALSE;
8143
8144 const clang::DeclContext *declDC = decl->getDeclContext();
8145 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8146 while (true) {
8147 if (declDC->isTransparentContext()) {
8148 declDC = declDC->getParent();
8149 continue;
8150 }
8151 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8152 if (declRD->isAnonymousStructOrUnion()) {
8153 declDC = declRD->getParent();
8154 continue;
8155 }
8156 }
8157 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8158 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8159 declDC = declNS->getParent();
8160 continue;
8161 }
8162 }
8163 break;
8164 }
8165
8166 return declDC->Equals(ctxt);
8167}
8168
8169////////////////////////////////////////////////////////////////////////////////
8170
8172{
8173 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8174 return TClinginfo->ClassProperty();
8175}
8176
8177////////////////////////////////////////////////////////////////////////////////
8178
8179void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8180{
8181 delete (TClingClassInfo*) cinfo;
8182}
8183
8184////////////////////////////////////////////////////////////////////////////////
8185
8186void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8187{
8188 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8189 TClinginfo->Delete(arena,*fNormalizedCtxt);
8190}
8191
8192////////////////////////////////////////////////////////////////////////////////
8193
8194void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8195{
8196 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8197 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8198}
8199
8200////////////////////////////////////////////////////////////////////////////////
8201
8202void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8203{
8204 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8205 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8206}
8207
8208////////////////////////////////////////////////////////////////////////////////
8209
8210ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8211{
8213 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8214}
8215
8216////////////////////////////////////////////////////////////////////////////////
8217
8218ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8219{
8220 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8221}
8222
8223////////////////////////////////////////////////////////////////////////////////
8224
8225ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8226{
8228 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8229}
8230
8231ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8232{
8234 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8235}
8236
8237
8238////////////////////////////////////////////////////////////////////////////////
8239
8240int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8241{
8242 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8243 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8244}
8245
8246////////////////////////////////////////////////////////////////////////////////
8247
8248bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8249{
8250 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8252}
8253
8254////////////////////////////////////////////////////////////////////////////////
8255
8256bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8257{
8258 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8259 return TClinginfo->HasMethod(name);
8260}
8261
8262////////////////////////////////////////////////////////////////////////////////
8263
8264void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8265{
8267 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8268 TClinginfo->Init(name);
8269}
8270
8271////////////////////////////////////////////////////////////////////////////////
8272
8273void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8274{
8276 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8277 TClinginfo->Init(tagnum);
8278}
8279
8280////////////////////////////////////////////////////////////////////////////////
8281
8282bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8283{
8284 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8285 return TClinginfo->IsBase(name);
8286}
8287
8288////////////////////////////////////////////////////////////////////////////////
8289
8290bool TCling::ClassInfo_IsEnum(const char* name) const
8291{
8293}
8294
8295////////////////////////////////////////////////////////////////////////////////
8296
8298{
8299 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8300 return TClinginfo->IsScopedEnum();
8301}
8302
8303
8304////////////////////////////////////////////////////////////////////////////////
8305
8307{
8308 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8309 return TClinginfo->GetUnderlyingType();
8310}
8311
8312
8313////////////////////////////////////////////////////////////////////////////////
8314
8315bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8316{
8317 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8318 return TClinginfo->IsLoaded();
8319}
8320
8321////////////////////////////////////////////////////////////////////////////////
8322
8323bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8324{
8325 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8326 return TClinginfo->IsValid();
8327}
8328
8329////////////////////////////////////////////////////////////////////////////////
8330
8331bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8332{
8333 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8334 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8335}
8336
8337////////////////////////////////////////////////////////////////////////////////
8338
8339bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8340{
8341 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8342 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8343}
8344
8345////////////////////////////////////////////////////////////////////////////////
8346
8347int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8348{
8349 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8350 return TClinginfo->Next();
8351}
8352
8353////////////////////////////////////////////////////////////////////////////////
8354
8355void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8356{
8357 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8358 return TClinginfo->New(*fNormalizedCtxt);
8359}
8360
8361////////////////////////////////////////////////////////////////////////////////
8362
8363void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8364{
8365 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8366 return TClinginfo->New(n,*fNormalizedCtxt);
8367}
8368
8369////////////////////////////////////////////////////////////////////////////////
8370
8371void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8372{
8373 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8374 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8375}
8376
8377////////////////////////////////////////////////////////////////////////////////
8378
8379void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8380{
8381 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8382 return TClinginfo->New(arena,*fNormalizedCtxt);
8383}
8384
8385////////////////////////////////////////////////////////////////////////////////
8386
8387Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8388{
8389 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8390 return TClinginfo->Property();
8391}
8392
8393////////////////////////////////////////////////////////////////////////////////
8394
8395int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8396{
8397 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8398 return TClinginfo->Size();
8399}
8400
8401////////////////////////////////////////////////////////////////////////////////
8402
8403Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8404{
8405 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8406 return TClinginfo->Tagnum();
8407}
8408
8409////////////////////////////////////////////////////////////////////////////////
8410
8411const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8412{
8413 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8414 return TClinginfo->FileName();
8415}
8416
8417////////////////////////////////////////////////////////////////////////////////
8418
8419const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8420{
8421 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8422 TTHREAD_TLS_DECL(std::string,output);
8423 TClinginfo->FullName(output,*fNormalizedCtxt);
8424 return output.c_str(); // NOLINT
8425}
8426
8427////////////////////////////////////////////////////////////////////////////////
8428
8429const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8430{
8431 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8432 return TClinginfo->Name();
8433}
8434
8435////////////////////////////////////////////////////////////////////////////////
8436
8437const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8438{
8439 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8440 return TClinginfo->Title();
8441}
8442
8443////////////////////////////////////////////////////////////////////////////////
8444
8445const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8446{
8447 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8448 return TClinginfo->TmpltName();
8449}
8450
8451
8452
8453//______________________________________________________________________________
8454//
8455// BaseClassInfo interface
8456//
8457
8458////////////////////////////////////////////////////////////////////////////////
8459
8460void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8461{
8462 delete(TClingBaseClassInfo*) bcinfo;
8463}
8464
8465////////////////////////////////////////////////////////////////////////////////
8466
8467BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8468{
8470 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8471 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8472}
8473
8474////////////////////////////////////////////////////////////////////////////////
8475
8476BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8477 ClassInfo_t* base) const
8478{
8480 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8481 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8482 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8483}
8484
8485////////////////////////////////////////////////////////////////////////////////
8486
8487int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8488{
8489 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8490 return TClinginfo->Next();
8491}
8492
8493////////////////////////////////////////////////////////////////////////////////
8494
8495int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8496{
8497 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8498 return TClinginfo->Next(onlyDirect);
8499}
8500
8501////////////////////////////////////////////////////////////////////////////////
8502
8503Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8504{
8505 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8506 return TClinginfo->Offset(address, isDerivedObject);
8507}
8508
8509////////////////////////////////////////////////////////////////////////////////
8510
8511Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8512{
8513 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8514 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8515 // Offset to the class itself.
8516 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8517 return 0;
8518 }
8519 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8520}
8521
8522////////////////////////////////////////////////////////////////////////////////
8523
8524Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8525{
8526 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8527 return TClinginfo->Property();
8528}
8529
8530////////////////////////////////////////////////////////////////////////////////
8531
8532ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8533{
8534 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8535 return (ClassInfo_t *)TClinginfo->GetBase();
8536}
8537
8538////////////////////////////////////////////////////////////////////////////////
8539
8540Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8541{
8542 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8543 return TClinginfo->Tagnum();
8544}
8545
8546////////////////////////////////////////////////////////////////////////////////
8547
8548const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8549{
8550 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8551 TTHREAD_TLS_DECL(std::string,output);
8552 TClinginfo->FullName(output,*fNormalizedCtxt);
8553 return output.c_str(); // NOLINT
8554}
8555
8556////////////////////////////////////////////////////////////////////////////////
8557
8558const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8559{
8560 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8561 return TClinginfo->Name();
8562}
8563
8564////////////////////////////////////////////////////////////////////////////////
8565
8566const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8567{
8568 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8569 return TClinginfo->TmpltName();
8570}
8571
8572//______________________________________________________________________________
8573//
8574// DataMemberInfo interface
8575//
8576
8577////////////////////////////////////////////////////////////////////////////////
8578
8579int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8580{
8581 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8582 return TClinginfo->ArrayDim();
8583}
8584
8585////////////////////////////////////////////////////////////////////////////////
8586
8587void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8588{
8589 delete(TClingDataMemberInfo*) dminfo;
8590}
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8594DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8595{
8597 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8598 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8599}
8600
8601////////////////////////////////////////////////////////////////////////////////
8602
8603DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8604{
8606 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8607 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8608 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8609}
8610
8611////////////////////////////////////////////////////////////////////////////////
8612
8613DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8614{
8615 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8616 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8617}
8618
8619////////////////////////////////////////////////////////////////////////////////
8620
8621bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8622{
8623 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8624 return TClinginfo->IsValid();
8625}
8626
8627////////////////////////////////////////////////////////////////////////////////
8628
8629int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8630{
8631 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8632 return TClinginfo->MaxIndex(dim);
8633}
8634
8635////////////////////////////////////////////////////////////////////////////////
8636
8637int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8638{
8639 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8640 return TClinginfo->Next();
8641}
8642
8643////////////////////////////////////////////////////////////////////////////////
8644
8645Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8646{
8647 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8648 return TClinginfo->Offset();
8649}
8650
8651////////////////////////////////////////////////////////////////////////////////
8652
8653Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8654{
8655 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8656 return TClinginfo->Property();
8657}
8658
8659////////////////////////////////////////////////////////////////////////////////
8660
8661Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8662{
8663 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8664 return TClinginfo->TypeProperty();
8665}
8666
8667////////////////////////////////////////////////////////////////////////////////
8668
8669int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8670{
8671 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8672 return TClinginfo->TypeSize();
8673}
8674
8675////////////////////////////////////////////////////////////////////////////////
8676
8677const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8678{
8679 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8680 return TClinginfo->TypeName();
8681}
8682
8683////////////////////////////////////////////////////////////////////////////////
8684
8685const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8686{
8687 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8688 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8689}
8690
8691////////////////////////////////////////////////////////////////////////////////
8692
8693const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8694{
8695 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8696 return TClinginfo->Name();
8697}
8698
8699////////////////////////////////////////////////////////////////////////////////
8700
8701const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8702{
8703 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8704 return TClinginfo->Title();
8705}
8706
8707////////////////////////////////////////////////////////////////////////////////
8708
8709const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8710{
8711 TTHREAD_TLS_DECL(std::string,result);
8712
8713 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8714 result = TClinginfo->ValidArrayIndex().str();
8715 return result.c_str(); // NOLINT
8716}
8717
8718////////////////////////////////////////////////////////////////////////////////
8719
8720void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8721{
8722 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8723 ASTContext &C = decl->getASTContext();
8724 SourceRange commentRange; // this is a fake comment range
8725 decl->addAttr( new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8726}
8727
8728//______________________________________________________________________________
8729//
8730// Function Template interface
8731//
8732
8733////////////////////////////////////////////////////////////////////////////////
8734
8735static void ConstructorName(std::string &name, const clang::Decl *decl,
8736 cling::Interpreter &interp,
8737 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8738{
8739 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8740 if (!td) return;
8741
8742 clang::QualType qualType(td->getTypeForDecl(),0);
8743 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8744 unsigned int level = 0;
8745 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8746 if (name[cursor] == '>') ++level;
8747 else if (name[cursor] == '<' && level) --level;
8748 else if (level == 0 && name[cursor] == ':') {
8749 name.erase(0,cursor+1);
8750 break;
8751 }
8752 }
8753}
8754
8755////////////////////////////////////////////////////////////////////////////////
8756
8757void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8758{
8759 output.clear();
8760
8761 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8762 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8763 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8764 }
8765 if (!FD) {
8766 Error("GetFunctionName", "NULL Decl!");
8767 return;
8768 }
8769
8770 // For using-decls, show "Derived", not "Base", i.e. use the
8771 // name of the decl context of the UsingShadowDecl (aka `decl`)
8772 // not the name of FD's decl context.
8773 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8774 {
8776
8777 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8778 {
8780 output.insert(output.begin(), '~');
8781 } else {
8782 llvm::raw_string_ostream stream(output);
8783 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8784 // Don't trigger fopen of the source file to count lines:
8785 printPolicy.AnonymousTagLocations = false;
8786 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8787 }
8788}
8789
8790////////////////////////////////////////////////////////////////////////////////
8791/// Return a unique identifier of the declaration represented by the
8792/// FuncTempInfo
8793
8795{
8796 return (DeclId_t)info;
8797}
8798
8799////////////////////////////////////////////////////////////////////////////////
8800/// Delete the FuncTempInfo_t
8801
8802void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8803{
8804 // Currently the address of ft_info is actually the decl itself,
8805 // so we have nothing to do.
8806}
8807
8808////////////////////////////////////////////////////////////////////////////////
8809/// Construct a FuncTempInfo_t
8810
8811FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8812{
8813 // Currently the address of ft_info is actually the decl itself,
8814 // so we have nothing to do.
8815
8816 return (FuncTempInfo_t*)const_cast<void*>(declid);
8817}
8818
8819////////////////////////////////////////////////////////////////////////////////
8820/// Construct a FuncTempInfo_t
8821
8822FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8823{
8824 // Currently the address of ft_info is actually the decl itself,
8825 // so we have nothing to do.
8826
8827 return (FuncTempInfo_t*)ft_info;
8828}
8829
8830////////////////////////////////////////////////////////////////////////////////
8831/// Check validity of a FuncTempInfo_t
8832
8833Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8834{
8835 // Currently the address of ft_info is actually the decl itself,
8836 // so we have nothing to do.
8837
8838 return t_info != 0;
8839}
8840
8841////////////////////////////////////////////////////////////////////////////////
8842/// Return the maximum number of template arguments of the
8843/// function template described by ft_info.
8844
8845UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8846{
8847 if (!ft_info) return 0;
8848 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8849 return ft->getTemplateParameters()->size();
8850}
8851
8852////////////////////////////////////////////////////////////////////////////////
8853/// Return the number of required template arguments of the
8854/// function template described by ft_info.
8855
8857{
8858 if (!ft_info) return 0;
8859 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8860 return ft->getTemplateParameters()->getMinRequiredArguments();
8861}
8862
8863////////////////////////////////////////////////////////////////////////////////
8864/// Return the property of the function template.
8865
8866Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8867{
8868 if (!ft_info) return 0;
8869
8870 long property = 0L;
8871 property |= kIsCompiled;
8872
8873 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8874
8875 switch (ft->getAccess()) {
8876 case clang::AS_public:
8877 property |= kIsPublic;
8878 break;
8879 case clang::AS_protected:
8880 property |= kIsProtected;
8881 break;
8882 case clang::AS_private:
8883 property |= kIsPrivate;
8884 break;
8885 case clang::AS_none:
8886 if (ft->getDeclContext()->isNamespace())
8887 property |= kIsPublic;
8888 break;
8889 default:
8890 // IMPOSSIBLE
8891 break;
8892 }
8893
8894 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8895 if (const clang::CXXMethodDecl *md =
8896 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8897 if (md->getMethodQualifiers().hasConst()) {
8898 property |= kIsConstant | kIsConstMethod;
8899 }
8900 if (md->isVirtual()) {
8901 property |= kIsVirtual;
8902 }
8903 if (md->isPure()) {
8904 property |= kIsPureVirtual;
8905 }
8906 if (const clang::CXXConstructorDecl *cd =
8907 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8908 if (cd->isExplicit()) {
8909 property |= kIsExplicit;
8910 }
8911 }
8912 else if (const clang::CXXConversionDecl *cd =
8913 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8914 if (cd->isExplicit()) {
8915 property |= kIsExplicit;
8916 }
8917 }
8918 }
8919 return property;
8920}
8921
8922////////////////////////////////////////////////////////////////////////////////
8923/// Return the property not already defined in Property
8924/// See TDictionary's EFunctionProperty
8925
8926Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8927{
8928 if (!ft_info) return 0;
8929
8930 long property = 0L;
8931 property |= kIsCompiled;
8932
8933 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8934 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8935
8936 if (fd->isOverloadedOperator())
8937 property |= kIsOperator;
8938 if (llvm::isa<clang::CXXConversionDecl>(fd))
8939 property |= kIsConversion;
8940 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8941 property |= kIsConstructor;
8942 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8943 property |= kIsDestructor;
8944 if (fd->isInlined())
8945 property |= kIsInlined;
8946 return property;
8947}
8948
8949////////////////////////////////////////////////////////////////////////////////
8950/// Return the name of this function template.
8951
8952void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8953{
8954 output.Clear();
8955 if (!ft_info) return;
8956 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8957 std::string buf;
8958 GetFunctionName(ft->getTemplatedDecl(), buf);
8959 output = buf;
8960}
8961
8962////////////////////////////////////////////////////////////////////////////////
8963/// Return the comments associates with this function template.
8964
8965void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8966{
8967 output.Clear();
8968 if (!ft_info) return;
8969 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8970
8971 // Iterate over the redeclarations, we can have multiple definitions in the
8972 // redecl chain (came from merging of pcms).
8973 if (const RedeclarableTemplateDecl *AnnotFD
8974 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8975 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8976 output = A->getAnnotation().str();
8977 return;
8978 }
8979 }
8980 if (!ft->isFromASTFile()) {
8981 // Try to get the comment from the header file if present
8982 // but not for decls from AST file, where rootcling would have
8983 // created an annotation
8985 }
8986}
8987
8988
8989//______________________________________________________________________________
8990//
8991// MethodInfo interface
8992//
8993
8994////////////////////////////////////////////////////////////////////////////////
8995/// Interface to cling function
8996
8997void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8998{
8999 delete(TClingMethodInfo*) minfo;
9000}
9001
9002////////////////////////////////////////////////////////////////////////////////
9003
9004void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9005{
9006 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9007 info->CreateSignature(signature);
9008}
9009
9010////////////////////////////////////////////////////////////////////////////////
9011
9012MethodInfo_t* TCling::MethodInfo_Factory() const
9013{
9015 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9016}
9017
9018////////////////////////////////////////////////////////////////////////////////
9019
9020MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9021{
9023 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9024}
9025
9026////////////////////////////////////////////////////////////////////////////////
9027
9028MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9029{
9030 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9032 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9033}
9034
9035////////////////////////////////////////////////////////////////////////////////
9036
9037MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9038{
9039 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9040}
9041
9042////////////////////////////////////////////////////////////////////////////////
9043
9044void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9045{
9046 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9047 return info->InterfaceMethod(*fNormalizedCtxt);
9048}
9049
9050////////////////////////////////////////////////////////////////////////////////
9051
9052bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9053{
9054 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9055 return info->IsValid();
9056}
9057
9058////////////////////////////////////////////////////////////////////////////////
9059
9060int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9061{
9062 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9063 return info->NArg();
9064}
9065
9066////////////////////////////////////////////////////////////////////////////////
9067
9068int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9069{
9070 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9071 return info->NDefaultArg();
9072}
9073
9074////////////////////////////////////////////////////////////////////////////////
9075
9076int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9077{
9078 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9079 return info->Next();
9080}
9081
9082////////////////////////////////////////////////////////////////////////////////
9083
9084Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9085{
9086 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9087 return info->Property();
9088}
9089
9090////////////////////////////////////////////////////////////////////////////////
9091
9093{
9094 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9095 return info->ExtraProperty();
9096}
9097
9098////////////////////////////////////////////////////////////////////////////////
9099
9100TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9101{
9102 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9103 return (TypeInfo_t*)info->Type();
9104}
9105
9106////////////////////////////////////////////////////////////////////////////////
9107
9108const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9109{
9110 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9111 TTHREAD_TLS_DECL(TString, mangled_name);
9112 mangled_name = info->GetMangledName();
9113 return mangled_name;
9114}
9115
9116////////////////////////////////////////////////////////////////////////////////
9117
9118const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9119{
9120 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9121 return info->GetPrototype();
9122}
9123
9124////////////////////////////////////////////////////////////////////////////////
9125
9126const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9127{
9128 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9129 return info->Name();
9130}
9131
9132////////////////////////////////////////////////////////////////////////////////
9133
9134const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9135{
9136 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9137 return info->TypeName();
9138}
9139
9140////////////////////////////////////////////////////////////////////////////////
9141
9142std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9143{
9144 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9145 if (info && info->IsValid())
9146 return info->Type()->NormalizedName(*fNormalizedCtxt);
9147 else
9148 return "";
9149}
9150
9151////////////////////////////////////////////////////////////////////////////////
9152
9153const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9154{
9155 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9156 return info->Title();
9157}
9158
9159////////////////////////////////////////////////////////////////////////////////
9160
9162{
9163 if (func) {
9164 return MethodInfo_MethodCallReturnType(func->fInfo);
9165 } else {
9166 return EReturnType::kOther;
9167 }
9168}
9169
9170////////////////////////////////////////////////////////////////////////////////
9171
9173{
9174 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9175 if (info && info->IsValid()) {
9176 TClingTypeInfo *typeinfo = info->Type();
9177 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9178 if (QT->isEnumeralType()) {
9179 return EReturnType::kLong;
9180 } else if (QT->isPointerType()) {
9181 // Look for char*
9182 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9183 if ( QT->isCharType() ) {
9184 return EReturnType::kString;
9185 } else {
9186 return EReturnType::kOther;
9187 }
9188 } else if ( QT->isFloatingType() ) {
9189 int sz = typeinfo->Size();
9190 if (sz == 4 || sz == 8) {
9191 // Support only float and double.
9192 return EReturnType::kDouble;
9193 } else {
9194 return EReturnType::kOther;
9195 }
9196 } else if ( QT->isIntegerType() ) {
9197 int sz = typeinfo->Size();
9198 if (sz <= 8) {
9199 // Support only up to long long ... but
9200 // FIXME the TMethodCall::Execute only
9201 // return long (4 bytes) ...
9202 // The v5 implementation of TMethodCall::ReturnType
9203 // was not making the distinction so we let it go
9204 // as is for now, but we really need to upgrade
9205 // TMethodCall::Execute ...
9206 return EReturnType::kLong;
9207 } else {
9208 return EReturnType::kOther;
9209 }
9210 } else {
9211 return EReturnType::kOther;
9212 }
9213 } else {
9214 return EReturnType::kOther;
9215 }
9216}
9217
9218//______________________________________________________________________________
9219//
9220// MethodArgInfo interface
9221//
9222
9223////////////////////////////////////////////////////////////////////////////////
9224
9225void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9226{
9227 delete(TClingMethodArgInfo*) marginfo;
9228}
9229
9230////////////////////////////////////////////////////////////////////////////////
9231
9232MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9233{
9235 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9236}
9237
9238////////////////////////////////////////////////////////////////////////////////
9239
9240MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9241{
9243 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9244}
9245
9246////////////////////////////////////////////////////////////////////////////////
9247
9248MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9249{
9250 return (MethodArgInfo_t*)
9252}
9253
9254////////////////////////////////////////////////////////////////////////////////
9255
9256bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9257{
9258 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9259 return info->IsValid();
9260}
9261
9262////////////////////////////////////////////////////////////////////////////////
9263
9264int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9265{
9266 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9267 return info->Next();
9268}
9269
9270////////////////////////////////////////////////////////////////////////////////
9271
9272Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9273{
9274 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9275 return info->Property();
9276}
9277
9278////////////////////////////////////////////////////////////////////////////////
9279
9280const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9281{
9282 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9283 return info->DefaultValue();
9284}
9285
9286////////////////////////////////////////////////////////////////////////////////
9287
9288const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9289{
9290 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9291 return info->Name();
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9296const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9297{
9298 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9299 return info->TypeName();
9300}
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9304std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9305{
9306 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9307 return info->Type()->NormalizedName(*fNormalizedCtxt);
9308}
9309
9310//______________________________________________________________________________
9311//
9312// TypeInfo interface
9313//
9314
9315////////////////////////////////////////////////////////////////////////////////
9316
9317void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9318{
9319 delete (TClingTypeInfo*) tinfo;
9320}
9321
9322////////////////////////////////////////////////////////////////////////////////
9323
9324TypeInfo_t* TCling::TypeInfo_Factory() const
9325{
9327 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331
9332TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9333{
9335 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9336}
9337
9338////////////////////////////////////////////////////////////////////////////////
9339
9340TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9341{
9342 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9343}
9344
9345////////////////////////////////////////////////////////////////////////////////
9346
9347void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9348{
9350 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9351 TClinginfo->Init(name);
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355
9356bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9357{
9358 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9359 return TClinginfo->IsValid();
9360}
9361
9362////////////////////////////////////////////////////////////////////////////////
9363
9364const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9365{
9366 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9367 return TClinginfo->Name();
9368}
9369
9370////////////////////////////////////////////////////////////////////////////////
9371
9372Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9373{
9374 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9375 return TClinginfo->Property();
9376}
9377
9378////////////////////////////////////////////////////////////////////////////////
9379
9380int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9381{
9382 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9383 return TClinginfo->RefType();
9384}
9385
9386////////////////////////////////////////////////////////////////////////////////
9387
9388int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9389{
9390 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9391 return TClinginfo->Size();
9392}
9393
9394////////////////////////////////////////////////////////////////////////////////
9395
9396const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9397{
9398 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9399 return TClinginfo->TrueName(*fNormalizedCtxt);
9400}
9401
9402
9403//______________________________________________________________________________
9404//
9405// TypedefInfo interface
9406//
9407
9408////////////////////////////////////////////////////////////////////////////////
9409
9410void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9411{
9412 delete(TClingTypedefInfo*) tinfo;
9413}
9414
9415////////////////////////////////////////////////////////////////////////////////
9416
9417TypedefInfo_t* TCling::TypedefInfo_Factory() const
9418{
9420 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9421}
9422
9423////////////////////////////////////////////////////////////////////////////////
9424
9425TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9426{
9428 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9429}
9430
9431////////////////////////////////////////////////////////////////////////////////
9432
9433TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9434{
9435 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9436}
9437
9438////////////////////////////////////////////////////////////////////////////////
9439
9440void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9441 const char* name) const
9442{
9444 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9445 TClinginfo->Init(name);
9446}
9447
9448////////////////////////////////////////////////////////////////////////////////
9449
9450bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9451{
9452 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9453 return TClinginfo->IsValid();
9454}
9455
9456////////////////////////////////////////////////////////////////////////////////
9457
9458Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9459{
9460 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9461 return TClinginfo->Next();
9462}
9463
9464////////////////////////////////////////////////////////////////////////////////
9465
9466Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9467{
9468 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9469 return TClinginfo->Property();
9470}
9471
9472////////////////////////////////////////////////////////////////////////////////
9473
9474int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9475{
9476 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9477 return TClinginfo->Size();
9478}
9479
9480////////////////////////////////////////////////////////////////////////////////
9481
9482const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9483{
9484 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9485 return TClinginfo->TrueName(*fNormalizedCtxt);
9486}
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9490const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9491{
9492 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9493 return TClinginfo->Name();
9494}
9495
9496////////////////////////////////////////////////////////////////////////////////
9497
9498const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9499{
9500 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9501 return TClinginfo->Title();
9502}
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9507{
9508 if (!fInitialMutex) {
9510 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9511 }
9513 }
9514 // We will "forget" this lock once we backed out of all interpreter frames.
9515 // Here we are entering one, so ++.
9517}
9518
9519////////////////////////////////////////////////////////////////////////////////
9520
9522{
9523 if (!fInitialMutex)
9524 return;
9525 if (fInitialMutex.fRecurseCount == 0) {
9526 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9527 }
9528 else if (--fInitialMutex.fRecurseCount == 0) {
9529 // We have returned from all interpreter frames. Reset the initial lock state.
9530 fInitialMutex.fState.reset();
9531 }
9532}
9533
9534////////////////////////////////////////////////////////////////////////////////
9535/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9536
9538{
9539 if (gInterpreterMutex) {
9540 if (delta) {
9541 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9542 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9543 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9544 // Now that we have the lock, update the global
9545 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9546 std::swap(fInitialMutex, typedDelta->fInitialState);
9547 } else {
9548 // This case happens when EnableThreadSafety is first called from
9549 // the interpreter function we just handled.
9550 // Since thread safety was not enabled at the time we rewound, there was
9551 // no lock taken and even-though we should be locking the rest of this
9552 // interpreter handling/modifying code (since there might be threads in
9553 // flight), we can't because there would not be any lock guard to release the
9554 // locks
9556 Error("ApplyToInterpreterMutex",
9557 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9558 "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.");
9559 }
9560 }
9561}
9562
9563////////////////////////////////////////////////////////////////////////////////
9564/// Reset the interpreter lock to the state it had before interpreter-related
9565/// calls happened.
9566
9568{
9569 if (fInitialMutex) {
9570 // Need to start a new recurse count.
9571 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9572 std::swap(uniqueP->fInitialState, fInitialMutex);
9573 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9574 return uniqueP.release();
9575 }
9577 return nullptr;
9578}
#define R__EXTERN
Definition DllImport.h:27
The file contains utilities which are foundational and could be used across the core component of ROO...
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
#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
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
const Ssiz_t kNPOS
Definition RtypesCore.h:124
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
const Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
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:1334
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7252
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:7006
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:3863
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:1953
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3098
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition TCling.cxx:3905
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:1087
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:1072
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:1682
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:1086
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:3881
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:6504
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:1190
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8735
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:2437
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:7163
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:1978
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:6248
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5432
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:1059
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:629
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7273
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:385
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:220
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:187
R__EXTERN Int_t gErrorIgnoreLevel
Definition TError.h:127
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
#define N
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:592
#define gROOT
Definition TROOT.h:404
char * Form(const char *fmt,...)
@ 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:16613
#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
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
static Longptr_t ExecuteFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
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:3425
EState GetState() const
Definition TClass.h:485
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2884
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:3784
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:4901
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:2203
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3384
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5945
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5735
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5690
@ 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:5898
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:6072
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2895
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4201
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1818
@ 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:3449
@ 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:2966
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)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
bool IsValid() const
Longptr_t ExecInt(void *address)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
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
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) 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 IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, 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
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:9280
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6120
virtual std::string CallFunc_GetWrapperCode(CallFunc_t *func) const
Definition TCling.cxx:8107
virtual void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const
Return the name of this function template.
Definition TCling.cxx:8952
virtual void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const
Return the comments associates with this function template.
Definition TCling.cxx:8965
virtual int TypedefInfo_Next(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9458
virtual bool DiagnoseIfInterpreterException(const std::exception &e) const
Definition TCling.cxx:2456
virtual bool ClassInfo_IsValid(ClassInfo_t *info) const
Definition TCling.cxx:8323
virtual bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const
Definition TCling.cxx:8297
Bool_t HasPCMForLibrary(const char *libname) const
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3116
virtual MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const
Definition TCling.cxx:9037
virtual const char * TypeInfo_Name(TypeInfo_t *) const
Definition TCling.cxx:9364
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:4949
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6484
void ForgetMutexState()
Definition TCling.cxx:9521
Longptr_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:3527
virtual bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const
Definition TCling.cxx:8256
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:139
virtual MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const
Definition TCling.cxx:7919
virtual bool MethodInfo_IsValid(MethodInfo_t *minfo) const
Definition TCling.cxx:9052
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:8685
void CreateListOfDataMembers(TClass *cl) const
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4415
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:2407
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:6901
virtual const char * MethodInfo_TypeName(MethodInfo_t *minfo) const
Definition TCling.cxx:9134
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const
Definition TCling.cxx:1918
virtual Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9466
virtual void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9225
virtual void LoadFunctionTemplates(TClass *cl) const
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4368
virtual CallFunc_t * CallFunc_Factory() const
Definition TCling.cxx:7904
virtual TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9433
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:150
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6775
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:7543
void UpdateListOfTypes()
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3857
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false)
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7289
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4870
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8579
virtual bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const
Definition TCling.cxx:8282
virtual int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8487
virtual void GenericError(const char *error) const
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7456
virtual std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9304
virtual const char * ClassInfo_TmpltName(ClassInfo_t *info) const
Definition TCling.cxx:8445
virtual TEnum * CreateEnum(void *VD, TClass *cl) const
Definition TCling.cxx:459
virtual EReturnType MethodCallReturnType(TFunction *func) const
Definition TCling.cxx:9161
virtual int UnloadFile(const char *path) const
Definition TCling.cxx:7645
virtual int Evaluate(const char *, TInterpreterValue &)
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7673
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7709
virtual Long_t TypeInfo_Property(TypeInfo_t *tinfo) const
Definition TCling.cxx:9372
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:5075
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7551
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6886
void EndOfLineAction()
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3090
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:5053
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3306
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:2024
virtual const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8709
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:5571
virtual Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const
Definition TCling.cxx:8511
void CreateListOfMethodArgs(TFunction *m) const
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4449
virtual void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const
Definition TCling.cxx:9440
virtual Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const
Definition TCling.cxx:9092
virtual void ReportDiagnosticsToErrorHandler(bool enable=true)
Report diagnostics to the ROOT error handler (see TError.h).
Definition TCling.cxx:7612
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1829
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1636
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7762
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:6648
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition TCling.cxx:5305
virtual void FuncTempInfo_Delete(FuncTempInfo_t *) const
Delete the FuncTempInfo_t.
Definition TCling.cxx:8802
Bool_t SetSuspendAutoParsing(Bool_t value)
Suspend the Autoparsing of headers.
Definition TCling.cxx:7593
virtual DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8613
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const
Definition TCling.cxx:7953
Longptr_t Calc(const char *line, EErrorCode *error=0)
Directly execute an executable statement (e.g.
Definition TCling.cxx:3543
virtual void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const
Definition TCling.cxx:7861
virtual MethodArgInfo_t * MethodArgInfo_Factory() const
Definition TCling.cxx:9232
virtual void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8587
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9537
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6545
virtual int LoadFile(const char *path) const
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7499
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &)
The call to Cling's tab complition.
Definition TCling.cxx:7665
virtual Long_t FuncTempInfo_Property(FuncTempInfo_t *) const
Return the property of the function template.
Definition TCling.cxx:8866
virtual TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const
Definition TCling.cxx:9100
virtual const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9296
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3623
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const
Definition TCling.cxx:8248
virtual bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8621
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:5448
Bool_t IsLoaded(const char *filename) const
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3141
const char * GetSharedLibs()
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6999
virtual const char * GetTopLevelMacroName() const
Return the file name of the current un-included interpreted file.
Definition TCling.cxx:5336
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:154
virtual DeclId_t GetDataMemberWithValue(const void *ptrvalue) const
NOT IMPLEMENTED.
Definition TCling.cxx:4861
virtual bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9256
Int_t ReloadAllSharedLibraryMaps()
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5853
virtual void SetErrmsgcallback(void *p) const
Set a callback to receive error messages.
Definition TCling.cxx:7603
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:9153
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8669
virtual ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const
Definition TCling.cxx:8210
virtual const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const
Definition TCling.cxx:9108
virtual bool CallFunc_IsValid(CallFunc_t *func) const
Definition TCling.cxx:7944
virtual const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8566
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:7533
virtual void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const
Definition TCling.cxx:9004
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx)
Definition TCling.cxx:9506
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:8126
std::set< size_t > fPayloads
Definition TCling.h:123
virtual const char * ClassInfo_Name(ClassInfo_t *info) const
Definition TCling.cxx:8429
Int_t UnloadLibraryMap(const char *library)
Unload library map entries coming from the specified library.
Definition TCling.cxx:5932
virtual ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const
Definition TCling.cxx:8532
TObjArray * fRootmapFiles
Definition TCling.h:127
virtual void CallFunc_Delete(CallFunc_t *func) const
Definition TCling.cxx:7838
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const
Definition TCling.cxx:8171
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:634
virtual bool ClassInfo_IsLoaded(ClassInfo_t *info) const
Definition TCling.cxx:8315
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:8240
virtual Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8540
Int_t DeleteGlobal(void *obj)
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3741
virtual const char * GetCurrentMacroName() const
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5383
virtual void TypeInfo_Delete(TypeInfo_t *tinfo) const
Definition TCling.cxx:9317
virtual Bool_t LoadText(const char *text) const
Load the declarations from text into the interpreter.
Definition TCling.cxx:7512
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:5120
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9567
virtual int GetSecurityError() const
Interface to cling function.
Definition TCling.cxx:7486
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:8856
void ResetGlobals()
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition TCling.cxx:3698
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=0)
Execute a cling macro.
Definition TCling.cxx:5323
virtual const char * ClassInfo_Title(ClassInfo_t *info) const
Definition TCling.cxx:8437
virtual void AddAvailableIndentifiers(TSeqCollection &Idents)
Definition TCling.cxx:2372
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8524
virtual FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const
Construct a FuncTempInfo_t.
Definition TCling.cxx:8811
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:4927
virtual void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const
Definition TCling.cxx:8202
virtual const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8548
virtual bool ClassInfo_IsEnum(const char *name) const
Definition TCling.cxx:8290
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const
Definition TCling.cxx:8594
virtual void TypedefInfo_Delete(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9410
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:3606
Int_t fGlobalsListSerial
Definition TCling.h:115
virtual Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const
Definition TCling.cxx:8503
void RewindDictionary()
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3727
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:7520
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6755
virtual bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const
Definition TCling.cxx:8331
virtual Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8926
void PrintIntro()
No-op; see TRint instead.
Definition TCling.cxx:2633
virtual CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const
Definition TCling.cxx:7912
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8693
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:3067
Int_t DeleteVariable(const char *name)
Undeclare obj called name.
Definition TCling.cxx:3756
virtual int ClassInfo_Next(ClassInfo_t *info) const
Definition TCling.cxx:8347
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:2647
virtual const char * MethodInfo_Name(MethodInfo_t *minfo) const
Definition TCling.cxx:9126
void ClearFileBusy()
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3046
virtual const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9288
virtual Long_t ClassInfo_Property(ClassInfo_t *info) const
Definition TCling.cxx:8387
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:9076
const char * TypeName(const char *typeDesc)
Return the absolute type of typeDesc.
Definition TCling.cxx:5398
bool fIsShuttingDown
Definition TCling.h:188
void SaveContext()
Save the current Cling state.
Definition TCling.cxx:3817
std::set< TClass * > & GetModTClasses()
Definition TCling.h:567
Longptr_t ProcessLine(const char *line, EErrorCode *error=0)
Definition TCling.cxx:2467
virtual bool TypeInfo_IsValid(TypeInfo_t *tinfo) const
Definition TCling.cxx:9356
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)
Load library containing the specified class.
Definition TCling.cxx:6181
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:4909
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:2398
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8653
void UpdateListOfGlobalFunctions()
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3850
virtual const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const
Definition TCling.cxx:9118
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=0)
Let cling process a command line asynch.
Definition TCling.cxx:3518
TString fIncludePath
Definition TCling.h:116
virtual Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const
Definition TCling.cxx:7880
virtual void * ClassInfo_New(ClassInfo_t *info) const
Definition TCling.cxx:8355
virtual void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const
Definition TCling.cxx:9347
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:7356
virtual const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8701
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6961
virtual EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const
Definition TCling.cxx:8306
virtual void CallFunc_Init(CallFunc_t *func) const
Definition TCling.cxx:7935
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:8845
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:4882
virtual void SetTempLevel(int val) const
Create / close a scope for temporaries.
Definition TCling.cxx:7639
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:4692
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7682
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:175
virtual void LoadEnums(TListOfEnums &cl) const
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4321
virtual void CallFunc_SetArg(CallFunc_t *func, Long_t param) const
Definition TCling.cxx:7969
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:7478
virtual void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const
Definition TCling.cxx:9044
Int_t UnloadAllSharedLibraryMaps()
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5914
virtual void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const
Definition TCling.cxx:7927
std::vector< cling::Value > * fTemporaries
Definition TCling.h:134
virtual Long_t MethodInfo_Property(MethodInfo_t *minfo) const
Definition TCling.cxx:9084
virtual std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const
Definition TCling.cxx:7658
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6072
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6984
virtual TypedefInfo_t * TypedefInfo_Factory() const
Definition TCling.cxx:9417
void UpdateListOfGlobals()
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3843
void ClearStack()
Delete existing temporary values.
Definition TCling.cxx:3054
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:7582
Bool_t fHeaderParsingOnDemand
Definition TCling.h:182
virtual int SetClassAutoLoading(int) const
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7564
Int_t RescanLibraryMap()
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5841
virtual int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8637
void Reset()
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3666
Int_t Load(const char *filenam, Bool_t system=kFALSE)
Load a library file in cling's memory.
Definition TCling.cxx:3473
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient)
Visit all members over members, recursing over base classes.
Definition TCling.cxx:2662
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:7370
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:8194
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8757
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:4752
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:4968
virtual Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8645
virtual void CallFunc_Exec(CallFunc_t *func, void *address) const
Definition TCling.cxx:7845
virtual int DisplayIncludePath(FILE *fout) const
Interface to cling function.
Definition TCling.cxx:7419
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3373
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:3830
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:126
void ProcessClassesToUpdate()
Definition TCling.cxx:1994
virtual Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9272
virtual const char * GetSTLIncludePath() const
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7401
TString fRootmapLoadPath
Definition TCling.h:117
Int_t LoadLibraryMap(const char *rootmapfile=0)
Load map between class and library.
Definition TCling.cxx:5657
virtual std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const
Definition TCling.cxx:9142
void Execute(const char *function, const char *params, int *error=0)
Execute a global function with arguments params.
Definition TCling.cxx:5153
virtual const char * ClassInfo_FullName(ClassInfo_t *info) const
Definition TCling.cxx:8419
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE)
Generate a TClass for the given class.
Definition TCling.cxx:4472
virtual Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const
Definition TCling.cxx:8403
virtual int TypeInfo_Size(TypeInfo_t *tinfo) const
Definition TCling.cxx:9388
virtual int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9264
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:136
virtual const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9482
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:6026
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4792
virtual std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4404
Int_t SetClassSharedLibs(const char *cls, const char *libs)
Register the AutoLoading information for a class.
Definition TCling.cxx:5994
virtual void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const
Definition TCling.cxx:8264
virtual TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const
Definition TCling.cxx:9340
Bool_t CheckClassTemplate(const char *name)
Return true if there is a class template by the given name ...
Definition TCling.cxx:4277
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1714
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6640
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:4442
virtual void SetDeclAttr(DeclId_t, const char *)
Definition TCling.cxx:8720
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8661
virtual void ShutDown()
Definition TCling.cxx:1673
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const
Definition TCling.cxx:8677
virtual void CallFunc_SetArgs(CallFunc_t *func, const char *param) const
Definition TCling.cxx:8025
virtual const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8558
virtual void MethodInfo_Delete(MethodInfo_t *minfo) const
Interface to cling function.
Definition TCling.cxx:8997
virtual void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const
Definition TCling.cxx:8033
virtual const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const
Definition TCling.cxx:9396
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:4105
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6749
virtual void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const
Definition TCling.cxx:8460
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:3712
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:131
Bool_t IsLibraryLoaded(const char *libname) const
Definition TCling.cxx:3107
virtual void Initialize()
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1654
virtual void * FindSym(const char *entry) const
Interface to cling function.
Definition TCling.cxx:7448
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const
Definition TCling.cxx:8629
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE)
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:3976
virtual int TypeInfo_RefType(TypeInfo_t *) const
Definition TCling.cxx:9380
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:3510
std::set< size_t > fLookedUpClasses
Definition TCling.h:122
virtual void CallFunc_ResetArg(CallFunc_t *func) const
Definition TCling.cxx:7961
virtual Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const
Definition TCling.cxx:7888
void ResetAll()
Reset the Cling state to its initial state.
Definition TCling.cxx:3682
virtual void ClassInfo_Delete(ClassInfo_t *info) const
Definition TCling.cxx:8179
virtual Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const
Definition TCling.cxx:7896
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:6297
virtual const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9498
void CreateListOfBaseClasses(TClass *cl) const
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4297
void RecursiveRemove(TObject *obj)
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3641
virtual MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9248
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6859
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6691
virtual void CallFunc_SetFuncProto(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *proto, Longptr_t *Offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
Interface to cling function.
Definition TCling.cxx:8060
virtual const char * ClassInfo_FileName(ClassInfo_t *info) const
Definition TCling.cxx:8411
virtual void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition TCling.cxx:7869
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:5097
virtual int MethodInfo_NArg(MethodInfo_t *minfo) const
Definition TCling.cxx:9060
virtual FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const
Construct a FuncTempInfo_t.
Definition TCling.cxx:8822
void * fAutoLoadCallBack
Definition TCling.h:148
virtual int TypedefInfo_Size(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9474
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:132
virtual const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9490
virtual int DisplayClass(FILE *fout, const char *name, int base, int start) const
Definition TCling.cxx:7410
const char * GetClassSharedLibs(const char *cls)
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7102
Bool_t IsErrorMessagesEnabled() const
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7342
ULong64_t fTransactionCount
Definition TCling.h:149
virtual Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8833
virtual BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const
Definition TCling.cxx:8467
virtual bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const
Definition TCling.cxx:9450
virtual MethodInfo_t * MethodInfo_Factory() const
Definition TCling.cxx:9012
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:6439
virtual EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const
Definition TCling.cxx:9172
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:5030
virtual TypeInfo_t * TypeInfo_Factory() const
Definition TCling.cxx:9324
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition TCling.h:120
virtual int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const
Definition TCling.cxx:9068
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:4644
void CreateListOfMethods(TClass *cl) const
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4424
void UpdateListOfMethods(TClass *cl) const
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4433
virtual void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const
Definition TCling.cxx:8017
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1696
virtual int ClassInfo_Size(ClassInfo_t *info) const
Definition TCling.cxx:8395
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6764
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6991
Collection abstract base class.
Definition TCollection.h:65
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
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:212
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:86
const char * GetValue() const
Definition TEnv.h:110
const char * GetName() const
Returns name of object.
Definition TEnv.h:109
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
THashList * GetTable() const
Definition TEnv.h:140
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:145
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:38
virtual void Add(TObject *obj)
Definition TList.h:81
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:307
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:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Add(TObject *obj)
Definition TObjArray.h:68
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:164
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Clear(Option_t *="")
Definition TObject.h:119
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:393
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:991
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:473
void MakeZombie()
Definition TObject.h:53
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
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:2720
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)
Describes a persistent version of a class.
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:2202
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:916
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2222
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:2336
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:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:846
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:837
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1663
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3971
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4252
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1071
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1536
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1855
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:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
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:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:854
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2495
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:935
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1793
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2032
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:440
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:2836
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:872
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1546
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1647
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:888
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:735
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2018
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:196
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:189
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:191
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:218
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:82
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:250
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
Definition TClassEdit.h:255
std::vector< std::string > fElements
Definition TClassEdit.h:141
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