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#define ROOT_compiledata_cxx
65#include "compiledata.h"
66#include "strlcpy.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 <CppInterOp/CppInterOp.h>
119
120#include "llvm/IR/GlobalValue.h"
121#include "llvm/IR/Module.h"
122
123#include "llvm/Support/DynamicLibrary.h"
124#include "llvm/Support/raw_ostream.h"
125#include "llvm/Support/Path.h"
126#include "llvm/Support/Process.h"
127#include "llvm/Object/ELFObjectFile.h"
128#include "llvm/Object/ObjectFile.h"
129#include "llvm/Object/SymbolicFile.h"
130#include "llvm/Support/FileSystem.h"
131
132#include <algorithm>
133#include <iostream>
134#include <cassert>
135#include <map>
136#include <set>
137#include <stdexcept>
138#include <cstdint>
139#include <cstdio>
140#include <fstream>
141#include <sstream>
142#include <string>
143#include <tuple>
144#include <typeinfo>
145#include <unordered_map>
146#include <unordered_set>
147#include <utility>
148#include <vector>
149#include <functional>
150#include <optional>
151
152#ifndef R__WIN32
153#include <cxxabi.h>
154#define R__DLLEXPORT __attribute__ ((visibility ("default")))
155#include <sys/stat.h>
156#endif
157#include <climits>
158#include <cstdio>
159
160#ifdef __APPLE__
161#include <dlfcn.h>
162#include <mach-o/dyld.h>
163#include <mach-o/loader.h>
164#endif // __APPLE__
165
166#ifdef R__UNIX
167#include <dlfcn.h>
168#endif
169
170#if defined(R__LINUX) || defined(R__FBSD)
171# ifndef _GNU_SOURCE
172# define _GNU_SOURCE
173# endif
174# include <link.h> // dl_iterate_phdr()
175#endif
176
177#if defined(__CYGWIN__)
178#include <sys/cygwin.h>
179#define HMODULE void *
180extern "C" {
181 __declspec(dllimport) void * __stdcall GetCurrentProcess();
182 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
183 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
184}
185#endif
186
187// Fragment copied from LLVM's raw_ostream.cpp
188#if defined(_MSC_VER)
189#ifndef STDIN_FILENO
190# define STDIN_FILENO 0
191#endif
192#ifndef STDOUT_FILENO
193# define STDOUT_FILENO 1
194#endif
195#ifndef STDERR_FILENO
196# define STDERR_FILENO 2
197#endif
198#ifndef R__WIN32
199//#if defined(HAVE_UNISTD_H)
200# include <unistd.h>
201//#endif
202#else
203#include "Windows4Root.h"
204#include <Psapi.h>
205#include <direct.h>
206#undef GetModuleFileName
207#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
208#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
209#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
210#define dlclose(library) ::FreeLibrary((HMODULE)library)
211#define R__DLLEXPORT __declspec(dllexport)
212#endif
213#endif
214
215//______________________________________________________________________________
216// These functions are helpers for debugging issues with non-LLVMDEV builds.
217//
218R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
219 return D->getDeclContext();
220}
221R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
223}
224R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
225 return llvm::dyn_cast<clang::RecordDecl>(DC);
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
228 return DC->dumpDeclContext();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
231 return D->dump();
232}
233R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
234 return FD->dump();
235}
237 return ((clang::Decl*)D)->dump();
238}
240 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
241 std::string name;
242 {
243 llvm::raw_string_ostream OS(name);
244 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
245 true /*Qualified*/);
246 }
247 printf("%s\n", name.c_str());
248 }
249}
250//______________________________________________________________________________
251// These functions are helpers for testing issues directly rather than
252// relying on side effects.
253// This is used for the test for ROOT-7462/ROOT-6070
255 return D->isInvalidDecl();
256}
259 assert(info && info->IsValid());
260 return info->GetDecl()->isInvalidDecl();
261}
262
263using std::string, std::vector;
264using namespace clang;
265using namespace ROOT;
266
267namespace {
268 static const std::string gInterpreterClassDef = R"ICF(
269#undef ClassDef
270#define ClassDef(name, id) \
271_ClassDefInterp_(name,id,virtual,) \
272static int DeclFileLine() { return __LINE__; }
273#undef ClassDefNV
274#define ClassDefNV(name, id) \
275_ClassDefInterp_(name,id,,) \
276static int DeclFileLine() { return __LINE__; }
277#undef ClassDefOverride
278#define ClassDefOverride(name, id) \
279_ClassDefInterp_(name,id,,override) \
280static int DeclFileLine() { return __LINE__; }
281)ICF";
282
283 static const std::string gNonInterpreterClassDef = R"ICF(
284#define __ROOTCLING__ 1
285#undef ClassDef
286#define ClassDef(name,id) \
287_ClassDefOutline_(name,id,virtual,) \
288static int DeclFileLine() { return __LINE__; }
289#undef ClassDefNV
290#define ClassDefNV(name, id)\
291_ClassDefOutline_(name,id,,)\
292static int DeclFileLine() { return __LINE__; }
293#undef ClassDefOverride
294#define ClassDefOverride(name, id)\
295_ClassDefOutline_(name,id,,override)\
296static int DeclFileLine() { return __LINE__; }
297)ICF";
298
299// The macros below use ::Error, so let's ensure it is included
300 static const std::string gClassDefInterpMacro = R"ICF(
301#include "TError.h"
302
303#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
304private: \
305public: \
306 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
307 static const char *Class_Name() { return #name; } \
308 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { \
309 static std::atomic<UChar_t> recurseBlocker(0); \
310 if (R__likely(recurseBlocker >= 2)) { \
311 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
312 } else if (recurseBlocker == 1) { \
313 return false; \
314 } else if (recurseBlocker++ == 0) { \
315 ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency = \
316 ::ROOT::Internal::HasConsistentHashMember(_QUOTE_(name)) || \
317 ::ROOT::Internal::HasConsistentHashMember(*IsA()); \
318 ++recurseBlocker; \
319 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
320 } \
321 return false; /* unreachable */ \
322 } \
323 static Version_t Class_Version() { return id; } \
324 static TClass *Dictionary() { return 0; } \
325 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
326 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
327 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
328 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
329 static const char *DeclFileName() { return __FILE__; } \
330 static int ImplFileLine() { return 0; } \
331 static const char *ImplFileName() { return __FILE__; }
332)ICF";
333}
335
336// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
337// ROOT (which uses rtti)
338
339////////////////////////////////////////////////////////////////////////////////
340/// Print a StackTrace!
341
342extern "C"
346
347////////////////////////////////////////////////////////////////////////////////
348/// Load a library.
349
350extern "C" int TCling__LoadLibrary(const char *library)
351{
353 return gSystem->Load(library, "", false);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
358
359extern "C" void TCling__RestoreInterpreterMutex(void *delta)
360{
361 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
362}
363
364////////////////////////////////////////////////////////////////////////////////
365/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
366/// which is extracted by error messages we get from callback from cling. Return true
367/// when the missing library was autoloaded.
368
369extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
370{
371 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Reset the interpreter lock to the state it had before interpreter-related
376/// calls happened.
377
379{
380 return ((TCling*)gCling)->RewindInterpreterMutex();
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Lock the interpreter.
385
387{
388 if (gInterpreterMutex) {
390 }
391 return nullptr;
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Unlock the interpreter.
396
398{
399 if (gInterpreterMutex) {
401 }
402}
403
404////////////////////////////////////////////////////////////////////////////////
405/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
406
407static void TCling__UpdateClassInfo(const NamedDecl* TD)
408{
409 static Bool_t entered = kFALSE;
410 static vector<const NamedDecl*> updateList;
411 Bool_t topLevel;
412
413 if (entered) topLevel = kFALSE;
414 else {
415 entered = kTRUE;
416 topLevel = kTRUE;
417 }
418 if (topLevel) {
419 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
420 } else {
421 // If we are called indirectly from within another call to
422 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
423 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
424 // This allows for the dictionary to be fully populated when we actually
425 // update the TClass object. The updating of the TClass sometimes
426 // (STL containers and when there is an emulated class) forces the building
427 // of the TClass object's real data (which needs the dictionary info).
428 updateList.push_back(TD);
429 }
430 if (topLevel) {
431 while (!updateList.empty()) {
432 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
433 updateList.pop_back();
434 }
435 entered = kFALSE;
436 }
437}
438
439void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
440 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
441 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
442 // Add the constants to the enum type.
443 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
444 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
445 // Get name of the enum type.
446 std::string constbuf;
447 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
448 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
449 llvm::raw_string_ostream stream(constbuf);
450 // Don't trigger fopen of the source file to count lines:
451 Policy.AnonymousTagLocations = false;
452 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
453 }
454 const char* constantName = constbuf.c_str();
455
456 // Get value of the constant.
458 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
459 if (valAPSInt.isSigned()) {
460 value = valAPSInt.getSExtValue();
461 } else {
462 value = valAPSInt.getZExtValue();
463 }
464
465 // Create the TEnumConstant or update it if existing
466 TEnumConstant* enumConstant = nullptr;
467 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
468 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
469 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
470 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
471 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
472 } else {
473 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
474 }
475
476 // Add the global constants to the list of Globals.
477 if (!cl) {
478 TCollection* globals = gROOT->GetListOfGlobals(false);
479 if (!globals->FindObject(constantName)) {
480 globals->Add(enumConstant);
481 }
482 }
483 }
484 }
485}
486
487TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
488{
489 // Handle new enum declaration for either global and nested enums.
490
491 // Create the enum type.
492 TEnum* enumType = nullptr;
493 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
494 std::string buf;
495 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
496 // Get name of the enum type.
497 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
498 llvm::raw_string_ostream stream(buf);
499 // Don't trigger fopen of the source file to count lines:
500 Policy.AnonymousTagLocations = false;
501 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
502 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
503 }
504 if (buf.empty()) {
505 return nullptr;
506 }
507 const char* name = buf.c_str();
508 enumType = new TEnum(name, VD, cl);
509 UpdateEnumConstants(enumType, cl);
510
511 return enumType;
512}
513
514void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
515 // Handle new declaration.
516 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
517
518 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
519
520 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
521 && !dyn_cast<clang::RecordDecl>(D)) return;
522
523 if (isa<clang::FunctionDecl>(D->getDeclContext())
524 || isa<clang::TagDecl>(D->getDeclContext()))
525 return;
526
527 // Don't list templates.
528 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
529 if (RD->getDescribedClassTemplate())
530 return;
531 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
532 if (FD->getDescribedFunctionTemplate())
533 return;
534 }
535
536 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
537 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
539 }
540 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
541
542 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
543 // Mostly just for EnumDecl (the other TagDecl are handled
544 // by the 'RecordDecl' if statement.
546 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
548 }
549
550 // We care about declarations on the global scope.
551 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
552 return;
553
554 // Enums are lazyly created, thus we don not need to handle them here.
555 if (isa<EnumDecl>(ND))
556 return;
557
558 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
559 // scope.
560 if (!(isa<VarDecl>(ND)))
561 return;
562
563 // Skip if already in the list.
564 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
565 return;
566
567 // Put the global constants and global enums in the corresponding lists.
568 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
570 cast<ValueDecl>(ND), nullptr)));
571 }
572}
573
574extern "C"
576{
577 // We are sure in this context of the type of the interpreter
578 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
579}
580
581extern "C"
582void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
583 ((TCling*)gCling)->UpdateListsOnCommitted(T);
584}
585
586extern "C"
587void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
588 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
589}
590
591extern "C"
592void TCling__InvalidateGlobal(const clang::Decl *D) {
593 ((TCling*)gCling)->InvalidateGlobal(D);
594}
595
596extern "C"
597void TCling__TransactionRollback(const cling::Transaction &T) {
598 ((TCling*)gCling)->TransactionRollback(T);
599}
600
601extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
602 const char* canonicalName) {
603 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
604}
605
606extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
607{
608 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
609}
610
611extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
612 const char* canonicalName) {
613 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
614}
615
616
617extern "C"
618TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
619 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
620}
621
622extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
623 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
624}
625
626extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
627 const char* argv[])
628{
629 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
630
631 return tcling;
632}
633
635{
636 delete interp;
637}
638
639// Load library containing specified class. Returns 0 in case of error
640// and 1 in case if success.
641extern "C" int TCling__AutoLoadCallback(const char* className)
642{
643 return ((TCling*)gCling)->AutoLoad(className);
644}
645
646extern "C" int TCling__AutoParseCallback(const char* className)
647{
648 return ((TCling*)gCling)->AutoParse(className);
649}
650
651extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
652{
653 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
654}
655
656// Returns 0 for failure 1 for success
657extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
658{
659 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
660}
661
662extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
663{
664 string file(fileName);
665 string opt(options);
666 return gSystem->CompileMacro(file.c_str(), opt.c_str());
667}
668
669extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
670 string &args, string &io, string &fname)
671{
672 string file(fileName);
673 TString f, amode, arguments, aclicio;
674 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
675 mode = amode.Data(); args = arguments.Data();
676 io = aclicio.Data(); fname = f.Data();
677}
678
679//______________________________________________________________________________
680//
681//
682//
683
684#ifdef R__WIN32
685extern "C" {
686 char *__unDName(char *demangled, const char *mangled, int out_len,
687 void * (* pAlloc )(size_t), void (* pFree )(void *),
688 unsigned short int flags);
689}
690#endif
691
692////////////////////////////////////////////////////////////////////////////////
693/// Find a template decl within N nested namespaces, 0<=N<inf
694/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
695/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
696/// Returns nullptr in case of error
697
698static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
699{
700 using namespace clang;
701 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
702 return FindTemplateInNamespace(*nsd->decls_begin());
703 }
704
705 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
706 return ctd;
707 }
708
709 return nullptr; // something went wrong.
710}
711
712//______________________________________________________________________________
713//
714//
715//
716
717int TCling_GenerateDictionary(const std::vector<std::string> &classes,
718 const std::vector<std::string> &headers,
719 const std::vector<std::string> &fwdDecls,
720 const std::vector<std::string> &unknown)
721{
722 //This function automatically creates the "LinkDef.h" file for templated
723 //classes then executes CompileMacro on it.
724 //The name of the file depends on the class name, and it's not generated again
725 //if the file exist.
726 if (classes.empty()) {
727 return 0;
728 }
729 // Use the name of the first class as the main name.
730 const std::string& className = classes[0];
731 //(0) prepare file name
732 TString fileName = "AutoDict_";
733 std::string::const_iterator sIt;
734 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
735 if (*sIt == '<' || *sIt == '>' ||
736 *sIt == ' ' || *sIt == '*' ||
737 *sIt == ',' || *sIt == '&' ||
738 *sIt == ':') {
739 fileName += '_';
740 }
741 else {
742 fileName += *sIt;
743 }
744 }
745 if (classes.size() > 1) {
746 Int_t chk = 0;
747 std::vector<std::string>::const_iterator it = classes.begin();
748 while ((++it) != classes.end()) {
749 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
750 chk = chk * 3 + it->at(cursor);
751 }
752 }
753 fileName += TString::Format("_%u", chk);
754 }
755 fileName += ".cxx";
756 if (gSystem->AccessPathName(fileName) != 0) {
757 //file does not exist
758 //(1) prepare file data
759 // If STL, also request iterators' operators.
760 // vector is special: we need to check whether
761 // vector::iterator is a typedef to pointer or a
762 // class.
763 static const std::set<std::string> sSTLTypes {
764 "vector","list","forward_list","deque","map","unordered_map","multimap",
765 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
766 "queue","priority_queue","stack","iterator"};
767 std::vector<std::string>::const_iterator it;
768 std::string fileContent("");
769 for (it = headers.begin(); it != headers.end(); ++it) {
770 fileContent += "#include \"" + *it + "\"\n";
771 }
772 for (it = unknown.begin(); it != unknown.end(); ++it) {
773 TClass* cl = TClass::GetClass(it->c_str());
774 if (cl && cl->GetDeclFileName()) {
775 TString header = gSystem->BaseName(cl->GetDeclFileName());
777 TString dirbase(gSystem->BaseName(dir));
778 while (dirbase.Length() && dirbase != "."
779 && dirbase != "include" && dirbase != "inc"
780 && dirbase != "prec_stl") {
781 gSystem->PrependPathName(dirbase, header);
782 dir = gSystem->GetDirName(dir);
783 }
784 fileContent += TString("#include \"") + header + "\"\n";
785 }
786 }
787 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
788 fileContent += "class " + *it + ";\n";
789 }
790 fileContent += "#ifdef __CLING__ \n";
791 fileContent += "#pragma link C++ nestedclasses;\n";
792 fileContent += "#pragma link C++ nestedtypedefs;\n";
793 for (it = classes.begin(); it != classes.end(); ++it) {
794 std::string n(*it);
795 size_t posTemplate = n.find('<');
796 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
797 if (posTemplate != std::string::npos) {
798 n.erase(posTemplate, std::string::npos);
799 if (n.compare(0, 5, "std::") == 0) {
800 n.erase(0, 5);
801 }
802 iSTLType = sSTLTypes.find(n);
803 }
804 fileContent += "#pragma link C++ class ";
805 fileContent += *it + "+;\n" ;
806 if (iSTLType == sSTLTypes.end()) {
807 // Not an STL class; we need to allow the I/O of contained
808 // classes (now that we have a dictionary for them).
809 fileContent += "#pragma link C++ class " + *it + "::*+;\n" ;
810 }
811 }
812 fileContent += "#endif\n";
813 //end(1)
814 //(2) prepare the file
815 FILE* filePointer;
816 filePointer = fopen(fileName, "w");
817 if (filePointer == nullptr) {
818 //can't open a file
819 return 1;
820 }
821 //end(2)
822 //write data into the file
823 fprintf(filePointer, "%s", fileContent.c_str());
824 fclose(filePointer);
825 }
826 //(3) checking if we can compile a macro, if not then cleaning
827 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
828 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
829 Int_t ret = gSystem->CompileMacro(fileName, "k");
830 gErrorIgnoreLevel = oldErrorIgnoreLevel;
831 if (ret == 0) { //can't compile a macro
832 return 2;
833 }
834 //end(3)
835 return 0;
836}
837
838int TCling_GenerateDictionary(const std::string& className,
839 const std::vector<std::string> &headers,
840 const std::vector<std::string> &fwdDecls,
841 const std::vector<std::string> &unknown)
842{
843 //This function automatically creates the "LinkDef.h" file for templated
844 //classes then executes CompileMacro on it.
845 //The name of the file depends on the class name, and it's not generated again
846 //if the file exist.
847 std::vector<std::string> classes;
848 classes.push_back(className);
849 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
850}
851
852//______________________________________________________________________________
853//
854//
855//
856
857// It is a "fantom" method to synchronize user keyboard input
858// and ROOT prompt line (for WIN32)
859const char* fantomline = "TRint::EndOfLineAction();";
860
861//______________________________________________________________________________
862//
863//
864//
865
866void* TCling::fgSetOfSpecials = nullptr;
867
868//______________________________________________________________________________
869//
870// llvm error handler through exceptions; see also cling/UserInterface
871//
872namespace {
873 // Handle fatal llvm errors by throwing an exception.
874 // Yes, throwing exceptions in error handlers is bad.
875 // Doing nothing is pretty terrible, too.
876 void exceptionErrorHandler(void * /*user_data*/,
877 const char *reason,
878 bool /*gen_crash_diag*/) {
879 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
880 }
881}
882
883//______________________________________________________________________________
884//
885//
886//
887
888////////////////////////////////////////////////////////////////////////////////
889
890namespace{
891 // An instance of this class causes the diagnostics of clang to be suppressed
892 // during its lifetime
893 class clangDiagSuppr {
894 public:
895 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
896 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
897 fDiagEngine.setIgnoreAllWarnings(true);
898 }
899
900 ~clangDiagSuppr() {
901 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
902 }
903 private:
904 clang::DiagnosticsEngine& fDiagEngine;
905 bool fOldDiagValue;
906 };
907
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Allow calling autoparsing from TMetaUtils
913{
914 return gCling->AutoParse(cname);
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Try hard to avoid looking up in the Cling database as this could enduce
919/// an unwanted autoparsing.
920
921bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
922 std::string &result)
923{
924 result.clear();
925
926 unsigned long offset = 0;
927 if (strncmp(tname.c_str(), "const ", 6) == 0) {
928 offset = 6;
929 }
930 unsigned long end = tname.length();
931 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
932 if ( tname[end-1]==']' ) {
933 --end;
934 while ( end && tname[end-1]!='[' ) --end;
935 }
936 --end;
937 }
938 std::string innerbuf;
939 const char *inner;
940 if (end != tname.length()) {
941 innerbuf = tname.substr(offset,end-offset);
942 inner = innerbuf.c_str();
943 } else {
944 inner = tname.c_str()+offset;
945 }
946
947 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
948 if (gROOT->GetListOfClasses()->FindObject(inner)
949 || TClassTable::Check(inner,result) ) {
950 // This is a known class.
951 return true;
952 }
953
954 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
955 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
956 if (type) {
957 // This is a raw type and an already loaded typedef.
958 const char *newname = type->GetFullTypeName();
959 if (type->GetType() == kLong64_t) {
960 newname = "Long64_t";
961 } else if (type->GetType() == kULong64_t) {
962 newname = "ULong64_t";
963 }
964 if (strcmp(inner,newname) == 0) {
965 return true;
966 }
967 if (offset) result = "const ";
968 result += newname;
969 if ( end != tname.length() ) {
970 result += tname.substr(end,tname.length()-end);
971 }
972 if (result == tname) result.clear();
973 return true;
974 }
975
976 // Check if the name is an enumerator
977 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
978 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
979 {
980 // We have a scope
981 const auto enName = lastPos;
982 const auto scopeNameSize = (lastPos - inner) / sizeof(decltype(*lastPos)) - 2;
983 std::string scopeName{inner, scopeNameSize};
984 // Check if the scope is in the list of classes
985 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName.c_str()))) {
986 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
987 if (enumTable && enumTable->THashList::FindObject(enName))
988 return true;
989 }
990 // It may still be in one of the loaded protoclasses
991 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName.c_str()))) {
992 auto listOfEnums = scope->GetListOfEnums();
993 if (listOfEnums) { // it could be null: no enumerators in the protoclass
994 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
995 if (enumTable && enumTable->THashList::FindObject(enName))
996 return true;
997 }
998 }
999 } else
1000 {
1001 // We don't have any scope: this could only be a global enum
1002 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
1003 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
1004 }
1005
1006 if (gCling->GetClassSharedLibs(inner))
1007 {
1008 // This is a class name.
1009 return true;
1010 }
1011
1012 return false;
1013}
1014
1015////////////////////////////////////////////////////////////////////////////////
1016/// Check if the class name is present in TClassTable.
1017///
1018/// \param[in] tname class name to check.
1019/// \param[out] result If a class name has an alternative name registered in
1020/// TClassTable, it will be copied into this string.
1021bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
1022{
1023 result.clear();
1024
1025 if (gROOT->GetListOfClasses()->FindObject(tname.c_str()) || TClassTable::Check(tname.c_str(), result)) {
1026 // This is a known class.
1027 return true;
1028 }
1029
1030 return false;
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034
1039
1040////////////////////////////////////////////////////////////////////////////////
1041
1043{
1044 return fContent.c_str();
1045}
1046
1047////////////////////////////////////////////////////////////////////////////////
1048/// Append string to the storage if not added already.
1049
1050inline bool TCling::TUniqueString::Append(const std::string& str)
1051{
1052 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1053 if (notPresent){
1054 fContent+=str;
1055 }
1056 return notPresent;
1057}
1058
1059std::string TCling::ToString(const char* type, void* obj)
1060{
1061 return fInterpreter->toString(type, obj);
1062}
1063
1064////////////////////////////////////////////////////////////////////////////////
1065///\returns true if the module was loaded.
1066static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1067{
1068 // When starting up ROOT, cling would load all modulemap files on the include
1069 // paths. However, in a ROOT session, it is very common to run aclic which
1070 // will invoke rootcling and possibly produce a modulemap and a module in
1071 // the current folder.
1072 //
1073 // Before failing, try loading the modulemap in the current folder and try
1074 // loading the requested module from it.
1075 std::string currentDir = gSystem->WorkingDirectory();
1076 assert(!currentDir.empty());
1078 if (gDebug > 2)
1079 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1080 ModuleName.c_str());
1081
1082 return interp.loadModule(ModuleName, /*Complain=*/true);
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Loads the C++ modules that we require to run any ROOT program. This is just
1087/// supposed to make a C++ module from a modulemap available to the interpreter.
1088static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1089{
1090 for (const auto &modName : modules)
1091 LoadModule(modName, interp);
1092}
1093
1094static bool IsFromRootCling() {
1095 // rootcling also uses TCling for generating the dictionary ROOT files.
1096 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1097 return foundSymbol;
1098}
1099
1100/// Checks if there is an ASTFile on disk for the given module \c M.
1101static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1102{
1103 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1104
1105 std::string ModuleFileName;
1106 if (!HSOpts.PrebuiltModulePaths.empty())
1107 // Load the module from *only* in the prebuilt module path.
1108 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1109 if (FullFileName)
1110 *FullFileName = ModuleFileName;
1111
1112 return !ModuleFileName.empty();
1113}
1114
1115static bool HaveFullGlobalModuleIndex = false;
1116static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1117{
1118 CompilerInstance &CI = *interp.getCI();
1119 Preprocessor &PP = CI.getPreprocessor();
1120 auto ModuleManager = CI.getASTReader();
1121 assert(ModuleManager);
1122 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1123 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1124 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1125 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1126 if (ModuleIndexPath.empty())
1127 return nullptr;
1128 // Get an existing global index. This loads it if not already loaded.
1129 ModuleManager->resetForReload();
1130 ModuleManager->loadGlobalIndex();
1131 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1132
1133 // For finding modules needing to be imported for fixit messages,
1134 // we need to make the global index cover all modules, so we do that here.
1135 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1136 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1137 bool RecreateIndex = false;
1138 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1139 Module *TheModule = I->second;
1140 // We want the index only of the prebuilt modules.
1141 if (!HasASTFileOnDisk(TheModule, PP))
1142 continue;
1143 LoadModule(TheModule->Name, interp);
1144 RecreateIndex = true;
1145 }
1146 if (RecreateIndex) {
1147 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1148 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1149
1150 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1151 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1152 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1153 TraverseDecl(TU);
1154 }
1155 bool VisitNamedDecl(NamedDecl *ND) {
1156 if (!ND->isFromASTFile())
1157 return true;
1158 if (!ND->getIdentifier())
1159 return true;
1160
1161 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1162 return true;
1163
1164 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1165 if (TD->isCompleteDefinition())
1166 Register(TD);
1167 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1168 Register(NSD, /*AddSingleEntry=*/ false);
1169 }
1170 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1171 Register(TND);
1172 // FIXME: Add the rest...
1173 return true; // continue decending
1174 }
1175 private:
1176 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1177 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1178 assert(ND->isFromASTFile());
1179 // FIXME: All decls should have an owning module once rootcling
1180 // updates its generated decls from within the LookupHelper & co.
1181 if (!ND->hasOwningModule()) {
1182#ifndef NDEBUG
1183 SourceManager &SM = ND->getASTContext().getSourceManager();
1184 SourceLocation Loc = ND->getLocation();
1185 OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
1186 (void)FE;
1187 assert(FE->getName().contains("input_line_"));
1188#endif
1189 return;
1190 }
1191
1192 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1193 assert(OwningModule);
1194 assert(!ND->getName().empty() && "Empty name");
1195 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1196 return;
1197 // FIXME: The FileEntry in not stable to serialize.
1198 // FIXME: We might end up with many times with the same module.
1199 // FIXME: We might end up two modules containing a definition.
1200 // FIXME: What do we do if no definition is found.
1201 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1202 }
1203 };
1204 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1205
1206 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1207 CI.getPCHContainerReader(),
1208 ModuleIndexPath,
1209 &IDs));
1210 ModuleManager->resetForReload();
1211 ModuleManager->loadGlobalIndex();
1212 GlobalIndex = ModuleManager->getGlobalIndex();
1213 }
1215 }
1216 return GlobalIndex;
1217}
1218
1219static void RegisterCxxModules(cling::Interpreter &clingInterp)
1220{
1221 if (!clingInterp.getCI()->getLangOpts().Modules)
1222 return;
1223
1224 // Loading of a module might deserialize.
1225 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1226
1227 // Setup core C++ modules if we have any to setup.
1228
1229 // Load libc and stl first.
1230 // Load vcruntime module for windows
1231#ifdef R__WIN32
1232 LoadModule("vcruntime", clingInterp);
1233 LoadModule("services", clingInterp);
1234#endif
1235
1236#ifdef R__MACOSX
1237 LoadModule("Darwin", clingInterp);
1238#else
1239 LoadModule("libc", clingInterp);
1240#endif
1241 LoadModule("std", clingInterp);
1242
1243 LoadModule("_Builtin_intrinsics", clingInterp);
1244
1245 // Load core modules
1246 // This should be vector in order to be able to pass it to LoadModules
1247 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1248 "ROOT_Config",
1249 "ROOT_Rtypes",
1250 "ROOT_Foundation_Stage1_NoRTTI",
1251 "Core",
1252 "Rint",
1253 "RIO"};
1254
1255 LoadModules(CoreModules, clingInterp);
1256
1257 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1258 if (!IsFromRootCling()) {
1259 std::vector<std::string> CommonModules = {"MathCore"};
1260 LoadModules(CommonModules, clingInterp);
1261
1262 // These modules should not be preloaded but they fix issues.
1263 // FIXME: Hist is not a core module but is very entangled to MathCore and
1264 // causes issues.
1265 std::vector<std::string> FIXMEModules = {"Hist"};
1266 clang::CompilerInstance &CI = *clingInterp.getCI();
1267 clang::Preprocessor &PP = CI.getPreprocessor();
1268 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1269 if (MMap.findModule("RInterface"))
1270 FIXMEModules.push_back("RInterface");
1271
1272 LoadModules(FIXMEModules, clingInterp);
1273
1274 GlobalModuleIndex *GlobalIndex = nullptr;
1275
1276 bool useGMI = true;
1277 std::optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1278 if (envUseGMI.has_value())
1279 if (!envUseGMI->empty() && !ROOT::FoundationUtils::ConvertEnvValueToBool(*envUseGMI))
1280 useGMI = false;
1281
1282 if (useGMI) {
1283 loadGlobalModuleIndex(clingInterp);
1284 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1285 // We should investigate how to suppress it completely.
1286 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1287 }
1288
1289 llvm::StringSet<> KnownModuleFileNames;
1290 if (GlobalIndex)
1291 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1292
1293 std::vector<std::string> PendingModules;
1294 PendingModules.reserve(256);
1295 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1296 clang::Module *M = I->second;
1297 assert(M);
1298
1299 // We want to load only already created modules.
1300 std::string FullASTFilePath;
1301 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1302 continue;
1303
1304 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1305 continue;
1306
1307 if (M->IsUnimportable)
1308 continue;
1309
1310 if (GlobalIndex)
1311 LoadModule(M->Name, clingInterp);
1312 else {
1313 // FIXME: We may be able to remove those checks as cling::loadModule
1314 // checks if a module was alredy loaded.
1315 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1316 continue; // This is a core module which was already loaded.
1317
1318 // Load system modules now and delay the other modules after we have
1319 // loaded all system ones.
1320 if (M->IsSystem)
1321 LoadModule(M->Name, clingInterp);
1322 else
1323 PendingModules.push_back(M->Name);
1324 }
1325 }
1326 LoadModules(PendingModules, clingInterp);
1327 }
1328
1329 // Check that the gROOT macro was exported by any core module.
1330 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1331
1332 // `ERROR` and `PI` are from loading R related modules, which conflict with
1333 // user's code.
1334 clingInterp.declare(R"CODE(
1335#ifdef PI
1336# undef PI
1337#endif
1338#ifdef ERROR
1339# undef ERROR
1340#endif
1341 )CODE");
1342}
1343
1344static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1345{
1346 std::string PreIncludes;
1347 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1348
1349 // For the list to also include string, we have to include it now.
1350 // rootcling does parts already if needed, e.g. genreflex does not want using
1351 // namespace std.
1352 if (IsFromRootCling()) {
1353 PreIncludes += "#include \"RtypesCore.h\"\n";
1354 } else {
1355 if (!hasCxxModules)
1356 PreIncludes += "#include \"Rtypes.h\"\n";
1357
1358 PreIncludes += gClassDefInterpMacro + "\n"
1359 + gInterpreterClassDef + "\n"
1360 "#undef ClassImp\n" // bw compatibility
1361 "#define ClassImp(X);\n"; // bw compatibility
1362 }
1363 if (!hasCxxModules)
1364 PreIncludes += "#include <string>\n";
1365
1366 // We must include it even when we have modules because it is marked as
1367 // textual in the modulemap due to the nature of the assert header.
1368#ifndef R__WIN32
1369 PreIncludes += "#include <cassert>\n";
1370#endif
1371 PreIncludes += "using namespace std;\n";
1372 clingInterp.declare(PreIncludes);
1373}
1374
1375////////////////////////////////////////////////////////////////////////////////
1376/// Initialize the cling interpreter interface.
1377/// \param name name for TInterpreter
1378/// \param title title for TInterpreter
1379/// \param argv - array of arguments passed to the cling::Interpreter constructor
1380/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1381/// \param interpLibHandle handle to interpreter library
1382
1383TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1384: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1385 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr), fLookupHelper(nullptr),
1386 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1388{
1389 fPrompt[0] = 0;
1390 const bool fromRootCling = IsFromRootCling();
1391
1392 fCxxModulesEnabled = false;
1393#ifdef R__USE_CXXMODULES
1394 fCxxModulesEnabled = true;
1395#endif
1396
1397 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1398
1399 fTemporaries = new std::vector<cling::Value>();
1400
1401 std::vector<std::string> clingArgsStorage;
1402 clingArgsStorage.push_back("cling4root");
1403 for (const char* const* arg = argv; *arg; ++arg)
1404 clingArgsStorage.push_back(*arg);
1405
1406 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1407 if (!fromRootCling) {
1409
1410 // Add -I early so ASTReader can find the headers.
1411 std::string interpInclude(TROOT::GetEtcDir().Data());
1412 clingArgsStorage.push_back("-I" + interpInclude);
1413
1414 // Add include path to etc/cling.
1415 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1416
1417 // Add include path to etc/cling.
1418 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1419
1420 // Add the root include directory and etc/ to list searched by default.
1421 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1422
1423 // Add the current path to the include path
1424 // TCling::AddIncludePath(".");
1425
1426 // Attach the PCH (unless we have C++ modules enabled which provide the
1427 // same functionality).
1428 if (!fCxxModulesEnabled) {
1429 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1430 if (gSystem->Getenv("ROOT_PCH")) {
1431 pchFilename = gSystem->Getenv("ROOT_PCH");
1432 }
1433
1434 clingArgsStorage.push_back("-include-pch");
1435 clingArgsStorage.push_back(pchFilename);
1436 }
1437
1438 clingArgsStorage.push_back("-Wno-undefined-inline");
1439 clingArgsStorage.push_back("-fsigned-char");
1440 clingArgsStorage.push_back("-fsized-deallocation");
1441 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1442 // See the GitHub issues #9809 and #9944
1443 // TODO: to be reviewed after the upgrade of LLVM & Clang
1444#ifndef _MSC_VER
1445 clingArgsStorage.push_back("-O1");
1446 // Disable optimized register allocation which is turned on automatically
1447 // by -O1, but seems to require -O2 to not explode in run time.
1448 clingArgsStorage.push_back("-mllvm");
1449 clingArgsStorage.push_back("-optimize-regalloc=0");
1450#endif
1451
1452#ifdef CLING_WITH_ADAPTIVECPP
1453 std::string acppInclude(TROOT::GetIncludeDir() + "/AdaptiveCpp");
1454
1455 clingArgsStorage.push_back("-isystem");
1456 clingArgsStorage.push_back(acppInclude);
1457 clingArgsStorage.push_back("-mllvm");
1458 clingArgsStorage.push_back("-acpp-sscp");
1459#endif
1460 }
1461
1462 // Process externally passed arguments if present.
1463 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1464 if (EnvOpt.has_value()) {
1465 StringRef Env(*EnvOpt);
1466 while (!Env.empty()) {
1467 StringRef Arg;
1468 std::tie(Arg, Env) = Env.split(' ');
1469 clingArgsStorage.push_back(Arg.str());
1470 }
1471 }
1472
1473 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1474 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1475 if (EnvOpt.has_value()) {
1476 StringRef Env(*EnvOpt);
1477 while (!Env.empty()) {
1478 StringRef Arg;
1479 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1480 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1481 Paths.push_back(Arg.str());
1482 }
1483 }
1484 };
1485
1486 if (fCxxModulesEnabled) {
1487 std::vector<std::string> Paths;
1488 // ROOT usually knows better where its libraries are. This way we can
1489 // discover modules without having to should thisroot.sh and should fix
1490 // gnuinstall.
1491 Paths.push_back(TROOT::GetSharedLibDir().Data());
1492 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1493 std::string EnvVarPath;
1494 for (const std::string& P : Paths)
1496 // FIXME: We should make cling -fprebuilt-module-path work.
1497 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1498 }
1499
1500 // FIXME: This only will enable frontend timing reports.
1501 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1502 if (EnvOpt.has_value())
1503 clingArgsStorage.push_back("-ftime-report");
1504
1505 // Add the overlay file. Note that we cannot factor it out for both root
1506 // and rootcling because rootcling activates modules only if -cxxmodule
1507 // flag is passed.
1508 if (fCxxModulesEnabled && !fromRootCling) {
1509 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1510 std::vector<std::string> ModuleMaps;
1511 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1512 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1513 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1514
1515 std::string cwd = gSystem->WorkingDirectory();
1516 // Give highest precedence of the modulemap in the cwd if any.
1517 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1518 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1519
1520 for (const std::string& M : ModuleMaps)
1521 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1522
1523 std::string ModulesCachePath;
1524 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1525 if (EnvOpt.has_value()){
1526 StringRef Env(*EnvOpt);
1527 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1528 ModulesCachePath = Env.str();
1529 } else {
1530 ModulesCachePath = TROOT::GetSharedLibDir();
1531 }
1532
1533 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1534 }
1535
1536 std::vector<const char*> interpArgs;
1537 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1538 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1539 interpArgs.push_back(iArg->c_str());
1540
1541 // Activate C++ modules support. If we are running within rootcling, it's up
1542 // to rootcling to set this flag depending on whether it wants to produce
1543 // C++ modules.
1544 TString vfsArg;
1545 if (fCxxModulesEnabled) {
1546 if (!fromRootCling) {
1547 // We only set this flag, rest is done by the CIFactory.
1548 interpArgs.push_back("-fmodules");
1549 interpArgs.push_back("-fno-implicit-module-maps");
1550 // We should never build modules during runtime, so let's enable the
1551 // module build remarks from clang to make it easier to spot when we do
1552 // this by accident.
1553 interpArgs.push_back("-Rmodule-build");
1554 }
1555 // ROOT implements its AutoLoading upon module's link directives. We
1556 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1557 // facilities use the link directive to dynamically load the relevant
1558 // library. So, we need to suppress clang's default autolink behavior.
1559 interpArgs.push_back("-fno-autolink");
1560 }
1561
1562#ifdef R__FAST_MATH
1563 // Same setting as in rootcling_impl.cxx.
1564 interpArgs.push_back("-ffast-math");
1565#endif
1566
1567 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1568 // Add statically injected extra arguments, usually coming from rootcling.
1569 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1570 extraArgs && *extraArgs; ++extraArgs) {
1571 if (!strcmp(*extraArgs, "-resource-dir")) {
1572 // Take the next arg as the llvm resource directory.
1573 llvmResourceDir = *(++extraArgs);
1574 } else {
1575 interpArgs.push_back(*extraArgs);
1576 }
1577 }
1578
1579 std::vector<std::string> _empty;
1580 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1581 for (const auto &arg: args)
1582 interpArgs.emplace_back(arg.c_str());
1583
1584 // Add the Rdict module file extension.
1585 cling::Interpreter::ModuleFileExtensions extensions;
1586 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1587 if (!EnvOpt.has_value())
1588 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1589
1590 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1591 &(interpArgs[0]),
1592 llvmResourceDir, extensions,
1593 interpLibHandle);
1594
1595 if (!fInterpreter->getCI()) { // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1596 return;
1597 }
1598
1599 // Tell CppInterOp that the cling::Interpreter instance is managed externally by ROOT
1600 // Sets the interpreter by passing the fInterpreter handle as soon as TCling is initialized
1601 if (!IsFromRootCling())
1602 Cpp::UseExternalInterpreter(fInterpreter.get());
1603
1604 // Don't check whether modules' files exist.
1605 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1606 DisableValidationForModuleKind::All;
1607
1608 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1609 // to disable spell checking.
1610 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1611
1612 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1613 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1614 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1615 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1616
1617 // We need stream that doesn't close its file descriptor, thus we are not
1618 // using llvm::outs. Keeping file descriptor open we will be able to use
1619 // the results in pipes (Savannah #99234).
1620 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1621 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1622
1625
1626 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1632
1633 // Disallow auto-parsing in rootcling
1634 fIsAutoParsingSuspended = fromRootCling;
1635
1636 ResetAll();
1637
1638 // Enable dynamic lookup
1639 if (!fromRootCling) {
1640 fInterpreter->enableDynamicLookup();
1641 }
1642
1643 // Enable ClinG's DefinitionShadower for ROOT.
1644 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1645 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1646 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1647 // FIXME: We should probably switch to the default printing policy setting
1648 // after adjusting tons of reference files.
1649 Policy.SplitTemplateClosers = true;
1650 // Keep default templare arguments, required for dictionary generation.
1651 Policy.SuppressDefaultTemplateArgs = false;
1652
1653
1654 // Attach cling callbacks last; they might need TROOT::fInterpreter
1655 // and should thus not be triggered during the equivalent of
1656 // TROOT::fInterpreter = new TCling;
1657 std::unique_ptr<TClingCallbacks>
1658 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1659 fClingCallbacks = clingCallbacks.get();
1661 fInterpreter->setCallbacks(std::move(clingCallbacks));
1662
1663 if (!fromRootCling) {
1664 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1665 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1666 // e.g. because of an RPATH build.
1667 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1668 /*prepend=*/true);
1669 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1670 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1671 return stem.starts_with("libNew") || stem.starts_with("libcppyy_backend");
1672 };
1673 // Initialize the dyld for AutoloadLibraryGenerator.
1674 DLM.initializeDyld(ShouldPermanentlyIgnore);
1675 }
1676}
1677
1678
1679////////////////////////////////////////////////////////////////////////////////
1680/// Destroy the interpreter interface.
1681
1683{
1684 // ROOT's atexit functions require the interepreter to be available.
1685 // Run them before shutting down.
1686 if (!IsFromRootCling())
1687 GetInterpreterImpl()->runAtExitFuncs();
1688 fIsShuttingDown = true;
1689 delete fMapfile;
1690 delete fRootmapFiles;
1691 delete fTemporaries;
1692 delete fNormalizedCtxt;
1693 delete fLookupHelper;
1694 gCling = nullptr;
1695}
1696
1697////////////////////////////////////////////////////////////////////////////////
1698/// Initialize the interpreter, once TROOT::fInterpreter is set.
1699
1701{
1702 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1703 return;
1705
1706 // We are set up. Enable ROOT's AutoLoading.
1707 if (IsFromRootCling())
1708 return;
1709
1710 // Read the rules before enabling the auto loading to not inadvertently
1711 // load the libraries for the classes concerned even-though the user is
1712 // *not* using them.
1713 // Note this call must happen before the first call to LoadLibraryMap.
1714 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1715 TClass::ReadRules(); // Read the default customization rules ...
1716
1718 SetClassAutoLoading(true);
1719}
1720
1722{
1723 fIsShuttingDown = true;
1724 ResetGlobals();
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Helper to initialize TVirtualStreamerInfo's factor early.
1729/// Use static initialization to insure only one TStreamerInfo is created.
1731{
1732 // Use lambda since SetFactory return void.
1733 auto setFactory = []() {
1735 return kTRUE;
1736 };
1737 static bool doneFactory = setFactory();
1738 return doneFactory; // avoid unused variable warning.
1739}
1740
1741////////////////////////////////////////////////////////////////////////////////
1742/// Register Rdict data for future loading by LoadPCM;
1743
1744void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1745{
1746 if (IsFromRootCling())
1747 return;
1748
1749 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1750 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1751 return;
1752 }
1753
1754 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1755 // a link to a non-existent file.
1756 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1757}
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Tries to load a PCM from TFile; returns true on success.
1761/// The caller of this function should be holding the ROOT Write lock.
1762
1764{
1765 auto listOfKeys = pcmFile.GetListOfKeys();
1766
1767 // This is an empty pcm
1768 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1769 ((listOfKeys->GetSize() == 1) && // only one, and
1770 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1771 ))) {
1772 return;
1773 }
1774
1775 TObjArray *protoClasses;
1776 if (gDebug > 1)
1777 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1778
1779 TObjArray *enums;
1780 pcmFile.GetObject("__Enums", enums);
1781 if (enums) {
1782 // Cache the pointers
1783 auto listOfGlobals = gROOT->GetListOfGlobals();
1784 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1785 // Loop on enums and then on enum constants
1786 for (auto selEnum : *enums) {
1787 const char *enumScope = selEnum->GetTitle();
1788 const char *enumName = selEnum->GetName();
1789 if (strcmp(enumScope, "") == 0) {
1790 // This is a global enum and is added to the
1791 // list of enums and its constants to the list of globals
1792 if (!listOfEnums->THashList::FindObject(enumName)) {
1793 ((TEnum *)selEnum)->SetClass(nullptr);
1794 listOfEnums->Add(selEnum);
1795 }
1796 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1797 if (!listOfGlobals->FindObject(enumConstant)) {
1798 listOfGlobals->Add(enumConstant);
1799 }
1800 }
1801 } else {
1802 // This enum is in a namespace. A TClass entry is bootstrapped if
1803 // none exists yet and the enum is added to it
1804 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1805 if (!nsTClassEntry) {
1806 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1807 }
1808 auto listOfEnums = nsTClassEntry->fEnums.load();
1809 if (!listOfEnums) {
1810 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1811 // For this case, the list will be immutable once constructed
1812 // (i.e. in this case, by the end of this routine).
1813 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1814 } else {
1815 // namespaces can have enums added to them
1816 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1817 }
1818 }
1819 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1820 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1821 listOfEnums->Add(selEnum);
1822 }
1823 }
1824 }
1825 enums->Clear();
1826 delete enums;
1827 }
1828
1829 pcmFile.GetObject("__ProtoClasses", protoClasses);
1830
1831 if (protoClasses) {
1832 for (auto obj : *protoClasses) {
1833 TProtoClass *proto = (TProtoClass *)obj;
1834 TClassTable::Add(proto);
1835 }
1836 // Now that all TClass-es know how to set them up we can update
1837 // existing TClasses, which might cause the creation of e.g. TBaseClass
1838 // objects which in turn requires the creation of TClasses, that could
1839 // come from the PCH, but maybe later in the loop. Instead of resolving
1840 // a dependency graph the addition to the TClassTable above allows us
1841 // to create these dependent TClasses as needed below.
1842 for (auto proto : *protoClasses) {
1843 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1844 // We have an existing TClass object. It might be emulated
1845 // or interpreted; we now have more information available.
1846 // Make that available.
1847 if (existingCl->GetState() != TClass::kHasTClassInit) {
1848 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1849 if (!dict) {
1850 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1851 } else {
1852 // This will replace the existing TClass.
1853 TClass *ncl = (*dict)();
1854 if (ncl)
1855 ncl->PostLoadCheck();
1856 }
1857 }
1858 }
1859 }
1860
1861 protoClasses->Clear(); // Ownership was transferred to TClassTable.
1862 delete protoClasses;
1863 }
1864
1865 TObjArray *dataTypes;
1866 pcmFile.GetObject("__Typedefs", dataTypes);
1867 if (dataTypes) {
1868 for (auto typedf : *dataTypes)
1869 gROOT->GetListOfTypes()->Add(typedf);
1870 dataTypes->Clear(); // Ownership was transferred to TListOfTypes.
1871 delete dataTypes;
1872 }
1873}
1874
1875////////////////////////////////////////////////////////////////////////////////
1876/// Tries to load a rdict PCM, issues diagnostics if it fails.
1877/// The caller of this function should be holding the ROOT Write lock.
1878
1879void TCling::LoadPCM(std::string pcmFileNameFullPath)
1880{
1881 SuspendAutoLoadingRAII autoloadOff(this);
1882 SuspendAutoParsing autoparseOff(this);
1883 assert(!pcmFileNameFullPath.empty());
1884 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1885
1886 // Easier to work with the ROOT interfaces.
1887 TString pcmFileName = pcmFileNameFullPath;
1888
1889 // Prevent the ROOT-PCMs hitting this during auto-load during
1890 // JITting - which will cause recursive compilation.
1891 // Avoid to call the plugin manager at all.
1893
1895 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1896 if (gDebug > 5) {
1897 gDebug -= 5;
1898 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1899 } else {
1900 gDebug = 0;
1901 }
1902
1903 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1904 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1905
1906 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1907 if (pendingRdict != fPendingRdicts.end()) {
1908 llvm::StringRef pcmContent = pendingRdict->second;
1909 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1910 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1911 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1912
1913 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1914 LoadPCMImpl(pcmMemFile);
1915 // Currently the module file are never unloaded (even if the library is
1916 // unloaded) and, of course, never reloaded.
1917 // Consequently, we must NOT remove the `pendingRdict` from the list
1918 // of pending dictionary, otherwise if a library is unloaded and then
1919 // reload we will be unable to update properly the TClass object
1920 // (because we wont be able to load the rootpcm file by executing the
1921 // above lines)
1922
1923 return;
1924 }
1925
1926 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1927 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1928 pcmFileNameFullPath.data());
1929 if (!fPendingRdicts.empty())
1930 for (const auto &rdict : fPendingRdicts)
1931 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1932 rdict.first.c_str());
1933 return;
1934 }
1935
1936 if (!gROOT->IsRootFile(pcmFileName)) {
1937 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1938 return;
1939 }
1940 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1941 LoadPCMImpl(pcmFile);
1942}
1943
1944//______________________________________________________________________________
1945
1946namespace {
1947 using namespace clang;
1948
1949 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1950 // This class is to be considered an helper for autoparsing.
1951 // It visits the AST and marks all classes (in all of their redeclarations)
1952 // with the setHasExternalLexicalStorage method.
1953 public:
1954 bool VisitRecordDecl(clang::RecordDecl* rcd){
1955 if (gDebug > 2)
1956 Info("ExtLexicalStorageAdder",
1957 "Adding external lexical storage to class %s",
1958 rcd->getNameAsString().c_str());
1959 auto reDeclPtr = rcd->getMostRecentDecl();
1960 do {
1961 reDeclPtr->setHasExternalLexicalStorage();
1962 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1963
1964 return false;
1965 }
1966 };
1967
1968
1969}
1970
1971////////////////////////////////////////////////////////////////////////////////
1972///\returns true if the module map was loaded, false on error or if the map was
1973/// already loaded.
1974bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1975 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1976{
1977 assert(llvm::sys::path::is_absolute(FullPath));
1978 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1979 FileManager &FM = PP.getFileManager();
1980 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1981 // We should look for modulemap files there too.
1982 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1983 HeaderSearch &HS = PP.getHeaderSearchInfo();
1984 HeaderSearchOptions &HSOpts = const_cast<HeaderSearchOptions&>(HS.getHeaderSearchOpts());
1985 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1986 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1987 if (!pathExists)
1988 HSOpts.AddPrebuiltModulePath(FullPath);
1989 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1990 // because its internal call to getFile has CacheFailure set to true.
1991 // In our case, modulemaps can appear any time due to ACLiC.
1992 // Code copied from HS.lookupModuleMapFile.
1993 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1994 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1995 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1996 /*CacheFailure*/ false)) {
1997 if (!HS.parseAndLoadModuleMapFile(*FE, /*IsSystem*/ false))
1998 return true;
1999 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
2000 }
2001 }
2002 return false;
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// List of dicts that have the PCM information already in the PCH.
2007static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
2008 "libRint",
2009 "libThread",
2010 "libRIO",
2011 "libImt",
2012 "libMultiProc",
2013 "libcomplexDict",
2014 "libdequeDict",
2015 "liblistDict",
2016 "libforward_listDict",
2017 "libvectorDict",
2018 "libmapDict",
2019 "libmultimap2Dict",
2020 "libmap2Dict",
2021 "libmultimapDict",
2022 "libsetDict",
2023 "libmultisetDict",
2024 "libunordered_setDict",
2025 "libunordered_multisetDict",
2026 "libunordered_mapDict",
2027 "libunordered_multimapDict",
2028 "libvalarrayDict",
2029 "G__GenVector32",
2030 "G__Smatrix32"};
2031
2032static void PrintDlError(const char *dyLibName, const char *modulename)
2033{
2034#ifdef R__WIN32
2035 char dyLibError[1000];
2036 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2037 dyLibError, sizeof(dyLibError), NULL);
2038#else
2039 const char *dyLibError = dlerror();
2040#endif
2041 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2042 (dyLibError) ? dyLibError : "");
2043}
2044
2045////////////////////////////////////////////////////////////////////////////////
2046// Update all the TClass registered in fClassesToUpdate
2047
2049{
2050 while (!fClassesToUpdate.empty()) {
2051 TClass *oldcl = fClassesToUpdate.back().first;
2052 // If somehow the TClass has already been loaded (maybe it was registered several time),
2053 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2054 // maybe even kForwardDeclared and needs to replaced.
2055 if (oldcl->GetState() != TClass::kHasTClassInit) {
2056 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2057 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2058 fClassesToUpdate.pop_back();
2059 // Calling func could manipulate the list so, let maintain the list
2060 // then call the dictionary function.
2061 TClass *ncl = dict();
2062 if (ncl) ncl->PostLoadCheck();
2063 } else {
2064 fClassesToUpdate.pop_back();
2065 }
2066 }
2067}
2068////////////////////////////////////////////////////////////////////////////////
2069/// Inject the module named "modulename" into cling; load all headers.
2070/// headers is a 0-terminated array of header files to `#include` after
2071/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2072/// entries (or %PATH% on Windows).
2073/// This function gets called by the static initialization of dictionary
2074/// libraries.
2075/// The payload code is injected "as is" in the interpreter.
2076/// The value of 'triggerFunc' is used to find the shared library location.
2077/// The caller of this function should be holding the ROOT Write lock.
2078
2079void TCling::RegisterModule(const char* modulename,
2080 const char** headers,
2081 const char** includePaths,
2082 const char* payloadCode,
2083 const char* fwdDeclsCode,
2084 void (*triggerFunc)(),
2085 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2086 const char** classesHeaders,
2087 Bool_t lateRegistration /*=false*/,
2088 Bool_t hasCxxModule /*=false*/)
2089{
2090 const bool fromRootCling = IsFromRootCling();
2091 // We need the dictionary initialization but we don't want to inject the
2092 // declarations into the interpreter, except for those we really need for
2093 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2094 if (fromRootCling) return;
2095
2096 // When we cannot provide a module for the library we should enable header
2097 // parsing. This 'mixed' mode ensures gradual migration to modules.
2098 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2099 fHeaderParsingOnDemand = !hasCxxModule;
2100
2101 // Treat Aclic Libs in a special way. Do not delay the parsing.
2102 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2103 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2104 if (hasHeaderParsingOnDemand && isACLiC) {
2105 if (gDebug>1)
2106 Info("TCling::RegisterModule",
2107 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2108 hasHeaderParsingOnDemand = false;
2109 }
2110
2111
2112 // Make sure we relookup symbols that were search for before we loaded
2113 // their autoparse information. We could be more subtil and remove only
2114 // the failed one or only the one in this module, but for now this is
2115 // better than nothing.
2116 fLookedUpClasses.clear();
2117
2118 // Make sure we do not set off AutoLoading or autoparsing during the
2119 // module registration!
2120 SuspendAutoLoadingRAII autoLoadOff(this);
2121
2122 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2123 TCling::AddIncludePath(*inclPath);
2124 }
2125 cling::Transaction* T = nullptr;
2126 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2127 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2128 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2129 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2130 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2131 assert(cling::Interpreter::kSuccess == compRes &&
2132 "A fwd declaration could not be compiled");
2133 if (compRes!=cling::Interpreter::kSuccess){
2134 Warning("TCling::RegisterModule",
2135 "Problems in declaring string '%s' were encountered.",
2136 fwdDecl.c_str()) ;
2137 continue;
2138 }
2139
2140 // Drill through namespaces recursively until the template is found
2141 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2142 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2143 }
2144
2145 }
2146
2147 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2148 // This is used to give Sema the same view on ACLiC'ed files (which
2149 // are then #included through the dictionary) as rootcling had.
2150 TString code = gNonInterpreterClassDef;
2151 if (payloadCode)
2152 code += payloadCode;
2153
2154 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2155 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2156
2157 if (dyLibName.empty()) {
2158 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2159 return;
2160 }
2161
2162 // The triggerFunc may not be in a shared object but in an executable.
2163 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2164
2165 bool wasDlopened = false;
2166
2167 // If this call happens after dlopen has finished (i.e. late registration)
2168 // there is no need to dlopen the library recursively. See ROOT-8437 where
2169 // the dyLibName would correspond to the binary.
2170 if (!lateRegistration) {
2171
2172 if (isSharedLib) {
2173 // We need to open the dictionary shared library, to resolve symbols
2174 // requested by the JIT from it: as the library is currently being dlopen'ed,
2175 // its symbols are not yet reachable from the process.
2176 // Recursive dlopen seems to work just fine.
2177 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2178 if (dyLibHandle) {
2179 fRegisterModuleDyLibs.push_back(dyLibHandle);
2180 wasDlopened = true;
2181 } else {
2182 PrintDlError(dyLibName.c_str(), modulename);
2183 }
2184 }
2185 } // if (!lateRegistration)
2186
2187 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2188 // We now parse the forward declarations. All the classes are then modified
2189 // in order for them to have an external lexical storage.
2190 std::string fwdDeclsCodeLessEnums;
2191 {
2192 // Search for enum forward decls and only declare them if no
2193 // declaration exists yet.
2194 std::string fwdDeclsLine;
2195 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2196 std::vector<std::string> scopes;
2197 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2198 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2199 // We check if the line contains a fwd declaration of an enum
2200 if (enumPos != std::string::npos) {
2201 // We clear the scopes which we may have carried from a previous iteration
2202 scopes.clear();
2203 // We check if the enum is not in a scope. If yes, save its name
2204 // and the names of the enclosing scopes.
2205 if (enumPos != 0) {
2206 // it's enclosed in namespaces. We need to understand what they are
2207 auto nsPos = fwdDeclsLine.find("namespace");
2208 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2209 while (nsPos < enumPos && nsPos != std::string::npos) {
2210 // we have a namespace, let's put it in the collection of scopes
2211 const auto nsNameStart = nsPos + 10;
2212 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2213 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2214 scopes.push_back(nsName);
2215 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2216 }
2217 }
2218 clang::DeclContext* DC = nullptr;
2219 for (auto &&aScope: scopes) {
2220 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2221 if (!DC) {
2222 // No decl context means we have to fwd declare the enum.
2223 break;
2224 }
2225 }
2226 if (scopes.empty() || DC) {
2227 // We know the scope; let's look for the enum. For that, look
2228 // for the *last* closing parentheses of an attribute because
2229 // there can be multiple.
2230 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2231 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2232 posEnumName += 5; // skip "\"))) "
2233 while (isspace(fwdDeclsLine[posEnumName]))
2234 ++posEnumName;
2235 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2236 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2237 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2238 --posEnumNameEnd;
2239 // posEnumNameEnd now points to the last character of the name.
2240
2241 std::string enumName = fwdDeclsLine.substr(posEnumName,
2242 posEnumNameEnd - posEnumName + 1);
2243
2244 if (clang::NamedDecl* enumDecl
2245 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2246 enumName.c_str(), DC)) {
2247 // We have an existing enum decl (forward or definition);
2248 // skip this.
2249 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2250 (void)enumDecl;
2251 continue;
2252 }
2253 }
2254 }
2255
2256 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2257 }
2258 }
2259
2260 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2261 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2262 assert(cling::Interpreter::kSuccess == compRes &&
2263 "The forward declarations could not be compiled");
2264 if (compRes!=cling::Interpreter::kSuccess){
2265 Warning("TCling::RegisterModule",
2266 "Problems in compiling forward declarations for module %s: '%s'",
2267 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2268 }
2269 else if (T){
2270 // Loop over all decls in the transaction and go through them all
2271 // to mark them properly.
2272 // In order to do that, we first iterate over all the DelayedCallInfos
2273 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2274 // contained in the DelayedCallInfos. For each decl, we traverse.
2275 ExtLexicalStorageAdder elsa;
2276 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2277 cling::Transaction::DelayCallInfo& dci = *dciIt;
2278 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2279 clang::Decl* declPtr = *dit;
2280 elsa.TraverseDecl(declPtr);
2281 }
2282 }
2283 }
2284 }
2285
2286 // Now we register all the headers necessary for the class
2287 // Typical format of the array:
2288 // {"A", "classes.h", "@",
2289 // "vector<A>", "vector", "@",
2290 // "myClass", payloadCode, "@",
2291 // nullptr};
2292
2293 std::string temp;
2294 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2295 temp=*classesHeader;
2296
2297 size_t theTemplateHash = 0;
2298 bool addTemplate = false;
2299 size_t posTemplate = temp.find('<');
2300 if (posTemplate != std::string::npos) {
2301 // Add an entry for the template itself.
2302 std::string templateName = temp.substr(0, posTemplate);
2303 theTemplateHash = fStringHashFunction(templateName);
2304 addTemplate = true;
2305 }
2306 size_t theHash = fStringHashFunction(temp);
2307 classesHeader++;
2308 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2309 // This is done in order to distinguish headers from files and from the payloadCode
2310 if (payloadCode == *classesHeader_inner ){
2311 fPayloads.insert(theHash);
2312 if (addTemplate) fPayloads.insert(theTemplateHash);
2313 }
2314 if (gDebug > 2)
2315 Info("TCling::RegisterModule",
2316 "Adding a header for %s", temp.c_str());
2317 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2318 if (addTemplate) {
2319 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2320 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2321 }
2322 addTemplate = false;
2323 }
2324 }
2325 }
2326 }
2327
2328 clang::Sema &TheSema = fInterpreter->getSema();
2329
2330 bool ModuleWasSuccessfullyLoaded = false;
2331 if (hasCxxModule) {
2332 std::string ModuleName = modulename;
2333 if (llvm::StringRef(modulename).starts_with("lib"))
2334 ModuleName = llvm::StringRef(modulename).substr(3).str();
2335
2336 // In case we are directly loading the library via gSystem->Load() without
2337 // specifying the relevant include paths we should try loading the
2338 // modulemap next to the library location.
2339 clang::Preprocessor &PP = TheSema.getPreprocessor();
2340 std::string ModuleMapName;
2341 if (isACLiC)
2342 ModuleMapName = ModuleName + ".modulemap";
2343 else
2344 ModuleMapName = "module.modulemap";
2345 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2346 ModuleMapName);
2347
2348 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2349 // modules such as GenVector32 because it needs to fall back to GenVector.
2350 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2351 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2352 if (!ModuleWasSuccessfullyLoaded) {
2353 // Only report if we found the module in the modulemap.
2354 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2355 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2356 if (moduleMap.findModule(ModuleName))
2357 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2358 }
2359 }
2360
2361 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2362 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2363 // The path dyLibName might not be absolute. This can happen if dyLibName
2364 // is linked to an executable in the same folder.
2365 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2366 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2367 llvm::sys::path::append(pcmFileNameFullPath,
2369 // A library built with C++ modules may ship only its .pcm and no
2370 // <lib>_rdict.pcm (the dictionary payload then lives in the C++ module).
2371 // In that case probing the legacy rootpcm makes LoadPCM emit a spurious
2372 // "ROOT PCM ... file does not exist" error followed by an in-memory
2373 // candidate dump. Skip the probe only when the C++ module was loaded AND
2374 // there is genuinely no rootpcm to load -- neither registered in-memory
2375 // (an embedded rdict, the check mirrors LoadPCM) nor present on disk. For
2376 // libraries without a C++ module the behaviour is unchanged, so a truly
2377 // missing rootpcm is still reported.
2378 std::string pcmPath = pcmFileNameFullPath.str().str();
2379 std::string pcmRealPath = llvm::sys::fs::is_symlink_file(pcmPath)
2381 : pcmPath;
2382 if (!ModuleWasSuccessfullyLoaded || fPendingRdicts.count(pcmRealPath) ||
2383 llvm::sys::fs::exists(pcmRealPath))
2384 LoadPCM(pcmPath);
2385 }
2386
2387 { // scope within which diagnostics are de-activated
2388 // For now we disable diagnostics because we saw them already at
2389 // dictionary generation time. That won't be an issue with the PCMs.
2390
2391 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2392
2393#if defined(R__MUST_REVISIT)
2394#if R__MUST_REVISIT(6,2)
2395 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2396#endif
2397#endif
2398
2399 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2400 SuspendAutoParsing autoParseRaii(this);
2401
2402 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2403 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2404 if (isACLiC) {
2405 // Register an unload point.
2406 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2407 }
2408
2409 assert(cling::Interpreter::kSuccess == compRes &&
2410 "Payload code of a dictionary could not be parsed correctly.");
2411 if (compRes!=cling::Interpreter::kSuccess) {
2412 Warning("TCling::RegisterModule",
2413 "Problems declaring payload for module %s.", modulename) ;
2414 }
2415 }
2416 }
2417
2418 // Now that all the header have been registered/compiled, let's
2419 // make sure to 'reset' the TClass that have a class init in this module
2420 // but already had their type information available (using information/header
2421 // loaded from other modules or from class rules or from opening a TFile
2422 // or from loading header in a way that did not provoke the loading of
2423 // the library we just loaded).
2425
2426 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2427 // __ROOTCLING__ might be pulled in through PCH
2428 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2429 "#undef __ROOTCLING__\n"
2430 + gInterpreterClassDef +
2431 "#endif");
2432 }
2433
2434 if (wasDlopened) {
2435 assert(isSharedLib);
2436 void* dyLibHandle = fRegisterModuleDyLibs.back();
2437 fRegisterModuleDyLibs.pop_back();
2438 dlclose(dyLibHandle);
2439 }
2440}
2441
2443 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2444 ASTContext &C = CI.getASTContext();
2445
2446 // Do not do anything if we have no global module index.
2447 // FIXME: This is mostly to real with false positives in the TTabCom
2448 // interface for non-modules.
2449 if (!fCxxModulesEnabled)
2450 return;
2451
2452 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2453 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2454 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2455 std::string I = Ident.str();
2456 if (!Idents.Contains(I.data()))
2457 Idents.Add(new TObjString(I.c_str()));
2458 }
2459 }
2460}
2461
2462
2463////////////////////////////////////////////////////////////////////////////////
2464/// Register classes that already existed prior to their dictionary loading
2465/// and that already had a ClassInfo (and thus would not be refresh via
2466/// UpdateClassInfo.
2467
2469{
2470 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2471}
2472
2473////////////////////////////////////////////////////////////////////////////////
2474/// If the dictionary is loaded, we can remove the class from the list
2475/// (otherwise the class might be loaded twice).
2476
2478{
2479 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2480 iterator stop = fClassesToUpdate.end();
2481 for(iterator i = fClassesToUpdate.begin();
2482 i != stop;
2483 ++i)
2484 {
2485 if ( i->first == oldcl ) {
2486 fClassesToUpdate.erase(i);
2487 return;
2488 }
2489 }
2490}
2491
2492
2493////////////////////////////////////////////////////////////////////////////////
2494/// Let cling process a command line.
2495///
2496/// If the command is executed and the error is 0, then the return value
2497/// is the int value corresponding to the result of the executed command
2498/// (float and double return values will be truncated).
2499///
2500
2501// Method for handling the interpreter exceptions.
2502// the MetaProcessor is passing in as argument to teh function, because
2503// cling::Interpreter::CompilationResult is a nested class and it cannot be
2504// forward declared, thus this method cannot be a static member function
2505// of TCling.
2506
2507static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2508 const char* input_line,
2509 cling::Interpreter::CompilationResult& compRes,
2510 cling::Value* result)
2511{
2512 try {
2513 return metaProcessor->process(input_line, compRes, result);
2514 }
2515 catch (cling::InterpreterException& ex)
2516 {
2517 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2518 ex.diagnose();
2519 compRes = cling::Interpreter::kFailure;
2520 }
2521 return 0;
2522}
2523
2524////////////////////////////////////////////////////////////////////////////////
2525
2526bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2527{
2528 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2529 ie->diagnose();
2530 return true;
2531 }
2532 return false;
2533}
2534
2535////////////////////////////////////////////////////////////////////////////////
2536
2538{
2539 // Copy the passed line, it comes from a static buffer in TApplication
2540 // which can be reentered through the Cling evaluation routines,
2541 // which would overwrite the static buffer and we would forget what we
2542 // were doing.
2543 //
2544 TString sLine(line);
2545 if (strstr(line,fantomline)) {
2546 // End-Of-Line action
2547 // See the comment (copied from above):
2548 // It is a "fantom" method to synchronize user keyboard input
2549 // and ROOT prompt line (for WIN32)
2550 // and is implemented by
2551 if (gApplication) {
2552 if (gApplication->IsCmdThread()) {
2554 gROOT->SetLineIsProcessing();
2555
2557
2558 gROOT->SetLineHasBeenProcessed();
2559 }
2560 }
2561 return 0;
2562 }
2563
2565 gGlobalMutex->Lock();
2566 if (!gInterpreterMutex)
2569 }
2571 gROOT->SetLineIsProcessing();
2572
2573 struct InterpreterFlagsRAII {
2574 cling::Interpreter* fInterpreter;
2575 bool fWasDynamicLookupEnabled;
2576
2577 InterpreterFlagsRAII(cling::Interpreter* interp):
2578 fInterpreter(interp),
2579 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2580 {
2581 fInterpreter->enableDynamicLookup(true);
2582 }
2583 ~InterpreterFlagsRAII() {
2584 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2585 gROOT->SetLineHasBeenProcessed();
2586 }
2587 } interpreterFlagsRAII(GetInterpreterImpl());
2588
2589 // A non-zero returned value means the given line was
2590 // not a complete statement.
2591 int indent = 0;
2592 // This will hold the resulting value of the evaluation the given line.
2593 cling::Value result;
2594 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2595 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2596 !strncmp(sLine.Data(), ".X", 2)) {
2597 // If there was a trailing "+", then CINT compiled the code above,
2598 // and we will need to strip the "+" before passing the line to cling.
2599 TString mod_line(sLine);
2600 TString aclicMode;
2601 TString arguments;
2602 TString io;
2603 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2604 aclicMode, arguments, io);
2605 if (aclicMode.Length()) {
2606 // Remove the leading '+'
2607 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2608 aclicMode[0]='k'; // We always want to keep the .so around.
2609 if (aclicMode[1]=='+') {
2610 // We have a 2nd +
2611 aclicMode[1]='f'; // We want to force the recompilation.
2612 }
2613 if (!gSystem->CompileMacro(fname,aclicMode)) {
2614 // ACLiC failed.
2615 compRes = cling::Interpreter::kFailure;
2616 } else {
2617 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2618 // if execution was requested.
2619
2620 if (arguments.Length() == 0) {
2621 arguments = "()";
2622 }
2623 // We need to remove the extension.
2624 Ssiz_t ext = fname.Last('.');
2625 if (ext != kNPOS) {
2626 fname.Remove(ext);
2627 }
2628 const char *function = gSystem->BaseName(fname);
2629 mod_line = function + arguments + io;
2631 }
2632 }
2633 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2634 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2635 if (gSystem->Load(fname) < 0) {
2636 // Loading failed.
2637 compRes = cling::Interpreter::kFailure;
2638 } else {
2639 if (arguments.Length() == 0) {
2640 arguments = "()";
2641 }
2642 // We need to remove the extension. (*.so or *.dll)
2643 Ssiz_t ext = fname.Last('.');
2644 if (ext != kNPOS) {
2645 fname.Remove(ext);
2646 }
2647 // Now we try to find the 'main' function to run within this shared library
2648 // We distinguish two cases: a library.so with a function library(args),
2649 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2650 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2651 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2652 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2653 ext = fname.Last('_');
2654 if (ext != kNPOS) {
2655 fname.Remove(ext);
2656 }
2657 }
2658 const char *function = gSystem->BaseName(fname);
2659 mod_line = function + arguments + io;
2661 }
2662 } else {
2663 // neither ACLiC nor run shared-library (.x)
2664 size_t unnamedMacroOpenCurly;
2665 {
2666 std::string code;
2667 std::string codeline;
2668 // Windows requires std::ifstream::binary to properly handle
2669 // CRLF and LF line endings
2670 std::ifstream in(fname, std::ifstream::binary);
2671 while (in) {
2672 std::getline(in, codeline);
2673 code += codeline + "\n";
2674 }
2675 unnamedMacroOpenCurly
2676 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2677 }
2678
2679 fCurExecutingMacros.push_back(fname);
2680 if (unnamedMacroOpenCurly != std::string::npos) {
2681 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2682 unnamedMacroOpenCurly);
2683 } else {
2684 // No DynLookup for .x, .L of named macros.
2685 fInterpreter->enableDynamicLookup(false);
2687 }
2688 fCurExecutingMacros.pop_back();
2689 }
2690 } // .L / .X / .x
2691 else {
2692 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2693 // explicitly ignore .autodict without having to support it
2694 // in cling.
2695
2696 // Turn off autoparsing if this is an include directive
2697 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2698 if (isInclusionDirective) {
2699 SuspendAutoParsing autoParseRaii(this);
2701 } else {
2703 }
2704 }
2705 }
2706 if (result.isValid())
2708 if (indent) {
2709 if (error)
2710 *error = kProcessing;
2711 return 0;
2712 }
2713 if (error) {
2714 switch (compRes) {
2715 case cling::Interpreter::kSuccess: *error = kNoError; break;
2716 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2717 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2718 }
2719 }
2720 if (compRes == cling::Interpreter::kSuccess
2721 && result.isValid()
2722 && !result.isVoid())
2723 {
2724 return result.castAs<Longptr_t>();
2725 }
2726 return 0;
2727}
2728
2729////////////////////////////////////////////////////////////////////////////////
2730/// No-op; see TRint instead.
2731
2733{
2734}
2735
2736////////////////////////////////////////////////////////////////////////////////
2737/// Print information about the interpreter.
2738///\param[in] option Selects the type of information to print.
2739///
2740/// List of currently support options:
2741/// - autoparsed: Print the list of classes that triggered autoparsing.
2743{
2744 if (option && *option) {
2745 if (!strcmp(option, "autoparsed")) {
2746 std::cout << "Auto parsed classes:" << std::endl;
2747 for (auto & cls : fAutoParseClasses) {
2748 std::cout << " " << cls << std::endl;
2749 }
2750 } else if (!strcmp(option, "autoloaded")) {
2751 std::cout << "Auto loaded libraries:" << std::endl;
2752 for (auto & lib : fAutoLoadedLibraries) {
2753 std::cout << " " << lib << std::endl;
2754 }
2755 } else {
2756 ::Error("TCling::Print", "Unknown option '%s'", option);
2757 }
2758 } else {
2759 ::Info("TCling::Print", "No options specified");
2760 }
2761}
2762
2763
2764////////////////////////////////////////////////////////////////////////////////
2765/// \brief Add a directory to the list of directories in which the
2766/// interpreter looks for include files.
2767/// \param[in] path The path to the directory.
2768/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2769/// \b NOT supported.
2770/// \warning Only the path to the directory should be specified, without
2771/// prepending the \c -I prefix, i.e.
2772/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2773/// \c -I prefix is used it will be ignored.
2774void TCling::AddIncludePath(const char *path)
2775{
2777 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2778 // gCling->AddIncludePath() does not! Work around that inconsistency:
2779 if (path[0] == '-' && path[1] == 'I')
2780 path += 2;
2781 TString sPath(path);
2782 gSystem->ExpandPathName(sPath);
2783#ifdef _MSC_VER
2784 if (sPath.BeginsWith("/")) {
2785 char drive[3];
2786 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2787 sPath.Prepend(drive);
2788 }
2789#endif
2790 fInterpreter->AddIncludePath(sPath.Data());
2791}
2792
2793////////////////////////////////////////////////////////////////////////////////
2794/// Visit all members over members, recursing over base classes.
2795
2796void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2797 const TClass* cl, Bool_t isTransient)
2798{
2799 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2800 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
2802 }
2803
2804 if (!cl || cl->GetCollectionProxy()) {
2805 // We do not need to investigate the content of the STL
2806 // collection, they are opaque to us (and details are
2807 // uninteresting).
2808 return;
2809 }
2810
2811 static const TClassRef clRefString("std::string");
2812 if (clRefString == cl) {
2813 // We stream std::string without going through members..
2814 return;
2815 }
2816
2817 if (TClassEdit::IsStdArray(cl->GetName())) {
2818 // We treat std arrays as C arrays
2819 return;
2820 }
2821
2822 const char* cobj = (const char*) obj; // for ptr arithmetics
2823
2824 // Treat the case of std::complex in a special manner. We want to enforce
2825 // the layout of a stl implementation independent class, which is the
2826 // complex as implemented in ROOT5.
2827
2828 // A simple lambda to simplify the code
2829 auto inspInspect = [&] (ptrdiff_t offset){
2830 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2831 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2832 };
2833
2834 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2835 switch(complexType) {
2837 {
2838 break;
2839 }
2841 {
2842 inspInspect(sizeof(float));
2843 return;
2844 }
2846 {
2847 inspInspect(sizeof(double));
2848 return;
2849 }
2851 {
2852 inspInspect(sizeof(int));
2853 return;
2854 }
2856 {
2857 inspInspect(sizeof(long));
2858 return;
2859 }
2860 }
2861
2862 static clang::PrintingPolicy
2863 printPol(fInterpreter->getCI()->getLangOpts());
2864 if (printPol.Indentation) {
2865 // not yet initialized
2866 printPol.Indentation = 0;
2867 printPol.SuppressInitializers = true;
2868 }
2869
2870 const char* clname = cl->GetName();
2871 // Printf("Inspecting class %s\n", clname);
2872
2873 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2874 const clang::Decl *scopeDecl = nullptr;
2875 const clang::Type *recordType = nullptr;
2876
2877 if (cl->GetClassInfo()) {
2878 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2879 scopeDecl = clingCI->GetDecl();
2880 recordType = clingCI->GetType();
2881 } else {
2882 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2883 // Diags will complain about private classes:
2884 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2885 &recordType);
2886 }
2887 if (!scopeDecl) {
2888 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2889 return;
2890 }
2891 const clang::CXXRecordDecl* recordDecl
2892 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2893 if (!recordDecl) {
2894 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2895 return;
2896 }
2897
2898 {
2899 // Force possible deserializations first. We need to have no pending
2900 // Transaction when passing control flow to the inspector below (ROOT-7779).
2901 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2902
2903 astContext.getASTRecordLayout(recordDecl);
2904
2905 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2906 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2907 }
2908
2909 const clang::ASTRecordLayout& recLayout
2910 = astContext.getASTRecordLayout(recordDecl);
2911
2912 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2913 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2914 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2915 // cl->GetName());
2916 // }
2917 if (cl->Size() != recLayout.getSize().getQuantity()) {
2918 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2919 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2920 }
2921
2922 unsigned iNField = 0;
2923 // iterate over fields
2924 // FieldDecls are non-static, else it would be a VarDecl.
2925 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2926 eField = recordDecl->field_end(); iField != eField;
2927 ++iField, ++iNField) {
2928
2929
2930 clang::QualType memberQT = iField->getType();
2931 if (recordType) {
2932 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2933 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2934 }
2935 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2936 if (memberQT.isNull()) {
2937 std::string memberName;
2938 llvm::raw_string_ostream stream(memberName);
2939 // Don't trigger fopen of the source file to count lines:
2940 printPol.AnonymousTagLocations = false;
2941 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2942 stream.flush();
2943 Error("InspectMembers",
2944 "Cannot retrieve QualType for member %s while inspecting class %s",
2945 memberName.c_str(), clname);
2946 continue; // skip member
2947 }
2948 const clang::Type* memType = memberQT.getTypePtr();
2949 if (!memType) {
2950 std::string memberName;
2951 llvm::raw_string_ostream stream(memberName);
2952 // Don't trigger fopen of the source file to count lines:
2953 printPol.AnonymousTagLocations = false;
2954 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2955 stream.flush();
2956 Error("InspectMembers",
2957 "Cannot retrieve Type for member %s while inspecting class %s",
2958 memberName.c_str(), clname);
2959 continue; // skip member
2960 }
2961
2962 const clang::Type* memNonPtrType = memType;
2963 Bool_t ispointer = false;
2964 if (memNonPtrType->isPointerType()) {
2965 ispointer = true;
2966 clang::QualType ptrQT
2967 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2968 if (recordType) {
2969 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2970 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2971 }
2972 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2973 if (ptrQT.isNull()) {
2974 std::string memberName;
2975 llvm::raw_string_ostream stream(memberName);
2976 // Don't trigger fopen of the source file to count lines:
2977 printPol.AnonymousTagLocations = false;
2978 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2979 stream.flush();
2980 Error("InspectMembers",
2981 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2982 memberName.c_str(), clname);
2983 continue; // skip member
2984 }
2985 memNonPtrType = ptrQT.getTypePtr();
2986 }
2987
2988 // assemble array size(s): "[12][4][]"
2989 llvm::SmallString<8> arraySize;
2990 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2991 unsigned arrLevel = 0;
2992 bool haveErrorDueToArray = false;
2993 while (arrType) {
2994 ++arrLevel;
2995 arraySize += '[';
2996 const clang::ConstantArrayType* constArrType =
2997 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2998 if (constArrType) {
2999 constArrType->getSize().toStringUnsigned(arraySize);
3000 }
3001 arraySize += ']';
3002 clang::QualType subArrQT = arrType->getElementType();
3003 if (subArrQT.isNull()) {
3004 std::string memberName;
3005 llvm::raw_string_ostream stream(memberName);
3006 // Don't trigger fopen of the source file to count lines:
3007 printPol.AnonymousTagLocations = false;
3008 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
3009 stream.flush();
3010 Error("InspectMembers",
3011 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
3012 arrLevel, subArrQT.getAsString(printPol).c_str(),
3013 memberName.c_str(), clname);
3014 haveErrorDueToArray = true;
3015 break;
3016 }
3017 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
3018 }
3019 if (haveErrorDueToArray) {
3020 continue; // skip member
3021 }
3022
3023 // construct member name
3024 std::string fieldName;
3025 if (memType->isPointerType()) {
3026 fieldName = "*";
3027 }
3028
3029 // Check if this field has a custom ioname, if not, just use the one of the decl
3030 std::string ioname(iField->getName());
3031 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
3032 fieldName += ioname;
3033 fieldName += arraySize;
3034
3035 // get member offset
3036 // NOTE currently we do not support bitfield and do not support
3037 // member that are not aligned on 'bit' boundaries.
3038 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
3039 ptrdiff_t fieldOffset = offset.getQuantity();
3040
3041 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
3042 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
3043 // R__insp.InspectMember(fName, "fName.");
3044 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
3045
3046 // If the class has a custom streamer and the type of the filed is a
3047 // private enum, struct or class, skip it.
3048 if (!insp.IsTreatingNonAccessibleTypes()){
3049 auto iFiledQtype = iField->getType();
3050 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
3051 auto declAccess = tagDecl->getAccess();
3052 if (declAccess == AS_private || declAccess == AS_protected) {
3053 continue;
3054 }
3055 }
3056 }
3057
3058 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
3059
3060 if (!ispointer) {
3061 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
3062 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
3063 // nested objects get an extra call to InspectMember
3064 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
3065 std::string sFieldRecName;
3066 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
3068 clang::QualType(memNonPtrType,0),
3069 *fInterpreter,
3071 }
3072
3073 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3074 // if we can not find the member (which should not really happen),
3075 // let's consider it transient.
3076 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3077 if (!mbr || !mbr->IsPersistent())
3078 insp.IncrementNestedTransient();
3079 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3080 (fieldName + '.').c_str(), transient);
3081 if (!mbr || !mbr->IsPersistent())
3082 insp.DecrementNestedTransient();
3083
3084 }
3085 }
3086 } // loop over fields
3087
3088 // inspect bases
3089 // TNamed::ShowMembers(R__insp);
3090 unsigned iNBase = 0;
3091 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3092 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3093 iBase != eBase; ++iBase, ++iNBase) {
3094 clang::QualType baseQT = iBase->getType();
3095 if (baseQT.isNull()) {
3096 Error("InspectMembers",
3097 "Cannot find QualType for base number %d while inspecting class %s",
3098 iNBase, clname);
3099 continue;
3100 }
3101 const clang::CXXRecordDecl* baseDecl
3102 = baseQT->getAsCXXRecordDecl();
3103 if (!baseDecl) {
3104 Error("InspectMembers",
3105 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3106 iNBase, clname);
3107 continue;
3108 }
3109 TClass* baseCl=nullptr;
3110 std::string sBaseName;
3111 // Try with the DeclId
3112 std::vector<TClass*> foundClasses;
3113 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3114 if (foundClasses.size()==1){
3115 baseCl=foundClasses[0];
3116 } else {
3117 // Try with the normalised Name, as a fallback
3118 if (!baseCl){
3120 baseQT,
3121 *fInterpreter,
3123 baseCl = TClass::GetClass(sBaseName.c_str());
3124 }
3125 }
3126
3127 if (!baseCl){
3128 std::string qualNameForDiag;
3129 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3130 Error("InspectMembers",
3131 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3132 continue;
3133 }
3134
3135 int64_t baseOffset;
3136 if (iBase->isVirtual()) {
3137 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
3138 if (!isTransient) {
3139 Error("InspectMembers",
3140 "Base %s of class %s is virtual but no object provided",
3141 sBaseName.c_str(), clname);
3142 }
3144 } else {
3145 // We have an object to determine the vbase offset.
3147 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3148 if (ci && baseCi) {
3149 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3150 true /*isDerivedObj*/);
3151 if (baseOffset == -1) {
3152 Error("InspectMembers",
3153 "Error calculating offset of virtual base %s of class %s",
3154 sBaseName.c_str(), clname);
3155 }
3156 } else {
3157 Error("InspectMembers",
3158 "Cannot calculate offset of virtual base %s of class %s",
3159 sBaseName.c_str(), clname);
3160 continue;
3161 }
3162 }
3163 } else {
3164 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3165 }
3166 // TOFIX: baseCl can be null here!
3167 if (baseCl->IsLoaded()) {
3168 // For loaded class, CallShowMember will (especially for TObject)
3169 // call the virtual ShowMember rather than the class specific version
3170 // resulting in an infinite recursion.
3171 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3172 } else {
3173 baseCl->CallShowMembers(cobj + baseOffset,
3174 insp, isTransient);
3175 }
3176 } // loop over bases
3177}
3178
3179////////////////////////////////////////////////////////////////////////////////
3180/// Check if constructor exited correctly, ie the instance is in a valid state
3181/// \return true if there is a compiler instance available, false otherwise
3183{
3184 return fInterpreter->getCI() != nullptr;
3185}
3186
3187////////////////////////////////////////////////////////////////////////////////
3188/// Reset the interpreter internal state in case a previous action was not correctly
3189/// terminated.
3190
3192{
3193 // No-op there is not equivalent state (to be cleared) in Cling.
3194}
3195
3196////////////////////////////////////////////////////////////////////////////////
3197/// Delete existing temporary values.
3198
3200{
3201 // No-op for cling due to cling::Value.
3202}
3203
3204namespace {
3205 // Re-enable JIT symbol library autoloading (independently of class/dictionary
3206 // autoloading) for the lifetime of the object. See its use in TCling::Declare
3207 // and #16601.
3208 class EnableAutoLoadingForJITSymbolsRAII {
3209 TClingCallbacks *fCallbacks;
3210 bool fOldValue = false;
3211
3212 public:
3213 EnableAutoLoadingForJITSymbolsRAII(TClingCallbacks *callbacks) : fCallbacks(callbacks)
3214 {
3215 if (fCallbacks) {
3216 fOldValue = fCallbacks->IsAutoLoadingForJITSymbols();
3217 fCallbacks->SetAutoLoadingForJITSymbols(true);
3218 }
3219 }
3220 ~EnableAutoLoadingForJITSymbolsRAII()
3221 {
3222 if (fCallbacks)
3223 fCallbacks->SetAutoLoadingForJITSymbols(fOldValue);
3224 }
3225 };
3226}
3227
3228////////////////////////////////////////////////////////////////////////////////
3229/// Declare code to the interpreter, without any of the interpreter actions
3230/// that could trigger a re-interpretation of the code. I.e. make cling
3231/// behave like a compiler: no dynamic lookup, no input wrapping for
3232/// subsequent execution, no automatic provision of declarations but just a
3233/// plain `#include`.
3234/// Returns true on success, false on failure.
3235
3236bool TCling::Declare(const char* code)
3237{
3239
3240 SuspendAutoLoadingRAII autoLoadOff(this);
3241 SuspendAutoParsing autoParseRaii(this);
3242
3243 // The suspensions above make parsing behave like a plain compiler, but they also
3244 // gate the JIT's library autoloading - and a declared global's static initializer
3245 // may still need symbols from a not-yet-loaded library (e.g. TVectorT<float> from
3246 // libMatrix). Re-allow autoloading for such genuine JIT symbol resolution. #16601
3247 EnableAutoLoadingForJITSymbolsRAII autoLoadJITOn(fClingCallbacks);
3248
3249 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3250 fInterpreter->enableDynamicLookup(false);
3251 bool oldRawInput = fInterpreter->isRawInputEnabled();
3252 fInterpreter->enableRawInput(true);
3253
3254 Bool_t ret = LoadText(code);
3255
3256 fInterpreter->enableRawInput(oldRawInput);
3257 fInterpreter->enableDynamicLookup(oldDynLookup);
3258 return ret;
3259}
3260
3261////////////////////////////////////////////////////////////////////////////////
3262/// It calls a "fantom" method to synchronize user keyboard input
3263/// and ROOT prompt line.
3264
3269
3270// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3271// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3272// was already taking a lock.
3273static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3274{
3275 // Check shared library.
3276 TString tLibName(libname);
3277 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3278 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3279 return false;
3280}
3281
3282Bool_t TCling::IsLibraryLoaded(const char* libname) const
3283{
3285 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3286}
3287
3288////////////////////////////////////////////////////////////////////////////////
3289/// Return true if ROOT has cxxmodules pcm for a given library name.
3290// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3291Bool_t TCling::HasPCMForLibrary(const char *libname) const
3292{
3293 llvm::StringRef ModuleName(libname);
3294 ModuleName = llvm::sys::path::stem(ModuleName);
3295 ModuleName.consume_front("lib");
3296
3297 // FIXME: In case when the modulemap is not yet loaded we will return the
3298 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3299 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3300 // which may happen after calling this interface. Maybe we should also check
3301 // if there is a Event.pcm file and a module.modulemap, load it and return
3302 // true.
3303 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3304 clang::Module *M = moduleMap.findModule(ModuleName);
3305 return M && !M->IsUnimportable && M->getASTFile();
3306}
3307
3308////////////////////////////////////////////////////////////////////////////////
3309/// Return true if the file has already been loaded by cint.
3310/// We will try in this order:
3311/// actual filename
3312/// filename as a path relative to
3313/// the include path
3314/// the shared library path
3315
3317{
3319
3320 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3321 // cling::DynamicLibraryManager.
3322
3323 std::string file_name = filename;
3324 size_t at = std::string::npos;
3325 while ((at = file_name.find("/./")) != std::string::npos)
3326 file_name.replace(at, 3, "/");
3327
3328 std::string filesStr = "";
3329 llvm::raw_string_ostream filesOS(filesStr);
3330 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3331 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3332 filesOS.flush();
3333
3334 llvm::SmallVector<llvm::StringRef, 100> files;
3335 llvm::StringRef(filesStr).split(files, "\n");
3336
3337 std::set<std::string> fileMap;
3338 llvm::StringRef file_name_ref(file_name);
3339 // Fill fileMap; return early on exact match.
3340 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3341 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3342 if ((*iF) == file_name_ref) return kTRUE; // exact match
3343 fileMap.insert(iF->str());
3344 }
3345
3346 if (fileMap.empty()) return kFALSE;
3347
3348 // Check MacroPath.
3349 TString sFilename(file_name.c_str());
3351 && fileMap.count(sFilename.Data())) {
3352 return kTRUE;
3353 }
3354
3355 // Check IncludePath.
3356 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3357 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3358 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3359 while (incPath.Index(" :") != -1) {
3360 incPath.ReplaceAll(" :", ":");
3361 }
3362 incPath.Prepend(".:");
3363 sFilename = file_name.c_str();
3364 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3365 && fileMap.count(sFilename.Data())) {
3366 return kTRUE;
3367 }
3368
3369 // Check shared library.
3370 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3371 return kTRUE;
3372
3373 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3374 clang::ConstSearchDirIterator *CurDir = nullptr;
3375 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3376 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3377 auto FE = HS.LookupFile(file_name.c_str(),
3378 clang::SourceLocation(),
3379 /*isAngled*/ false,
3380 /*FromDir*/ nullptr, CurDir,
3381 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3382 clang::DirectoryEntryRef>>(),
3383 /*SearchPath*/ nullptr,
3384 /*RelativePath*/ nullptr,
3385 /*RequestingModule*/ nullptr,
3386 /*SuggestedModule*/ nullptr,
3387 /*IsMapped*/ nullptr,
3388 /*IsFrameworkFound*/ nullptr,
3389 /*SkipCache*/ false,
3390 /*BuildSystemModule*/ false,
3391 /*OpenFile*/ false,
3392 /*CacheFail*/ false);
3393 if (FE) {
3394 // check in the source manager if the file is actually loaded
3395 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3396 // this works only with header (and source) files...
3397 clang::FileID FID = SM.translateFile(*FE);
3398 if (!FID.isInvalid() && FID.getHashValue() == 0)
3399 return kFALSE;
3400 else {
3401 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3402 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3403 return kFALSE;
3404 if (!FID.isInvalid())
3405 return kTRUE;
3406 }
3407 // ...then check shared library again, but with full path now
3408 sFilename = FE->getName().str();
3409 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3410 && fileMap.count(sFilename.Data())) {
3411 return kTRUE;
3412 }
3413 }
3414 return kFALSE;
3415}
3416
3417
3418#if defined(R__MACOSX)
3419
3420////////////////////////////////////////////////////////////////////////////////
3421/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3422/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3423/// to `-lFOO` such that it can be passed to the linker.
3424/// This is a unique feature of macOS 11.
3425
3426static bool R__UpdateLibFileForLinking(TString &lib)
3427{
3428 const char *mapfile = nullptr;
3429#if __x86_64__
3430 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3431#elif __arm64__
3432 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3433#else
3434 #error unsupported architecture
3435#endif
3436 if (std::ifstream cacheMap{mapfile}) {
3437 std::string line;
3438 while (getline(cacheMap, line)) {
3439 if (line.find(lib) != std::string::npos) {
3440 lib.ReplaceAll("/usr/lib/lib","-l");
3441 lib.ReplaceAll(".dylib","");
3442 return true;
3443 }
3444 }
3445 return false;
3446 }
3447 return false;
3448}
3449#endif // R__MACOSX
3450
3451#if defined (R__LINUX) || defined (R__FBSD)
3452
3453////////////////////////////////////////////////////////////////////////////////
3454/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3455/// Collects opened libraries.
3456
3457static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3458{
3459 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3460 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3461
3462 auto newLibs = static_cast<std::vector<std::string>*>(data);
3463 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3464 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3465 if (info->dlpi_name && info->dlpi_name[0]
3466#if defined(R__FBSD)
3467 //skip the executable (with null addr)
3468 && info->dlpi_addr
3469 //has no path
3470 && strncmp(info->dlpi_name, "[vdso]", 6)
3471 //the linker does not like to be mmapped
3472 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3473 //with error message "mmap of entire address space failed: Cannot allocate memory"
3474 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3475#endif
3476 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3477 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3478 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3479 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3480 newLibs->emplace_back(info->dlpi_name);
3481 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3482 }
3483 // No matter what the doc says, return != 0 means "stop the iteration".
3484 return 0;
3485}
3486
3487#endif // R__LINUX || R__FBSD
3488
3489
3490////////////////////////////////////////////////////////////////////////////////
3491
3493{
3494#if defined(R__WIN32) || defined(__CYGWIN__)
3495 HMODULE hModules[1024];
3496 void *hProcess;
3497 unsigned long cbModules;
3498 unsigned int i;
3499 hProcess = (void *)::GetCurrentProcess();
3500 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3501 // start at 1 to skip the executable itself
3502 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3503 static const int bufsize = 260;
3504 wchar_t winname[bufsize];
3505 char posixname[bufsize];
3506 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3507#if defined(__CYGWIN__)
3508 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3509#else
3510 std::wstring wpath = winname;
3511 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3512 string path(wpath.begin(), wpath.end());
3513 strncpy(posixname, path.c_str(), bufsize);
3514#endif
3515 if (!fSharedLibs.Contains(posixname)) {
3516 RegisterLoadedSharedLibrary(posixname);
3517 }
3518 }
3519#elif defined(R__MACOSX)
3520 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3521 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3522
3523 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3524 // Skip non-dylibs
3525 if (mh->filetype == MH_DYLIB) {
3526 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3527 RegisterLoadedSharedLibrary(imageName);
3528 }
3529 }
3530
3531 ++imageIndex;
3532 }
3533 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3534#elif defined(R__LINUX) || defined(R__FBSD)
3535 // fPrevLoadedDynLibInfo is unused on Linux.
3536 (void) fPrevLoadedDynLibInfo;
3537
3538 std::vector<std::string> newLibs;
3539 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3540 for (auto &&lib: newLibs)
3541 RegisterLoadedSharedLibrary(lib.c_str());
3542#else
3543 Error("TCling::UpdateListOfLoadedSharedLibraries",
3544 "Platform not supported!");
3545#endif
3546}
3547
3548namespace {
3549template <int N>
3550static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3551 return !strncmp(haystack, needle, N - 1);
3552}
3553}
3554
3555////////////////////////////////////////////////////////////////////////////////
3556/// Register that a library was autoloaded either to provide a 'missing' symbol
3557/// or to provide a class (see TClass::GetClass and TROOT::LoadClass).
3558void TCling::RegisterAutoLoadedLibrary(const char *libname)
3559{
3560 fAutoLoadedLibraries.insert(libname);
3561}
3562
3563////////////////////////////////////////////////////////////////////////////////
3564/// Register a new shared library name with the interpreter; add it to
3565/// fSharedLibs.
3566
3568{
3569 // Ignore NULL filenames, aka "the process".
3570 if (!filename) return;
3571
3572 // Tell the interpreter that this library is available; all libraries can be
3573 // used to resolve symbols.
3574 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3575 if (!DLM->isLibraryLoaded(filename)) {
3576 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3577 }
3578
3579#if defined(R__MACOSX)
3580 // Check that this is not a system library that does not exist on disk.
3581 auto lenFilename = strlen(filename);
3582 auto isInMacOSSystemDir = [](const char *fn) {
3583 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3584 };
3585 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3586
3587 // These we should not link with (e.g. because they forward to .tbd):
3588 || StartsWithStrLit(filename, "/usr/lib/system/")
3589 || StartsWithStrLit(filename, "/usr/lib/libc++")
3590 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3591 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3592 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3593 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3594 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3595 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3596 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3597 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3598 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3599 || StartsWithStrLit(filename, "/usr/lib/libauto")
3600 || StartsWithStrLit(filename, "/usr/lib/libcups")
3601 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3602 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3603 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3604 || StartsWithStrLit(filename, "/usr/lib/libpam")
3605 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3606 || StartsWithStrLit(filename, "/usr/lib/libextension")
3607 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3608 || StartsWithStrLit(filename, "/usr/lib/liboah")
3609 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3610 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3611 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3612 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3613
3614 // The system lib is likely in macOS's blob.
3615 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3616
3617 // "Link against the umbrella framework 'System.framework' instead"
3618 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3619 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3620 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3621
3622 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3623 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3624 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3625 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3626 return;
3627 TString sFileName(filename);
3628 R__UpdateLibFileForLinking(sFileName);
3629 filename = sFileName.Data();
3630#elif defined(__CYGWIN__)
3631 // Check that this is not a system library
3632 static const int bufsize = 260;
3633 char posixwindir[bufsize];
3634 char *windir = std::getenv("WINDIR");
3635 if (windir)
3636 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3637 else
3638 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3639 if (strstr(filename, posixwindir) ||
3640 strstr(filename, "/usr/bin/cyg"))
3641 return;
3642#elif defined(R__WIN32)
3643 if (strstr(filename, "/Windows/"))
3644 return;
3645#elif defined (R__LINUX)
3646 if (strstr(filename, "/ld-linux")
3647 || strstr(filename, "linux-gnu/")
3648 || strstr(filename, "/libstdc++.")
3649 || strstr(filename, "/libgcc")
3650 || strstr(filename, "/libc.")
3651 || strstr(filename, "/libdl.")
3652 || strstr(filename, "/libm."))
3653 return;
3654#endif
3655 // Update string of available libraries.
3656 if (!fSharedLibs.IsNull()) {
3657 fSharedLibs.Append(" ");
3658 }
3660}
3661
3662////////////////////////////////////////////////////////////////////////////////
3663/// Load a library file in cling's memory.
3664/// if 'system' is true, the library is never unloaded.
3665/// Return 0 on success, -1 on failure.
3666
3667Int_t TCling::Load(const char* filename, Bool_t system)
3668{
3669 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3670
3671 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3673 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3674 std::string canonLib = DLM->lookupLibrary(filename);
3675 cling::DynamicLibraryManager::LoadLibResult res
3676 = cling::DynamicLibraryManager::kLoadLibNotFound;
3677 if (!canonLib.empty()) {
3678 if (system)
3679 res = DLM->loadLibrary(filename, system, true);
3680 else {
3681 // For the non system libs, we'd like to be able to unload them.
3682 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3683 cling::Interpreter::CompilationResult compRes;
3684 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3685 if (compRes == cling::Interpreter::kSuccess)
3686 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3687 }
3688 }
3689
3690 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3692 }
3693 switch (res) {
3694 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3695 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3696 default: break;
3697 };
3698 return -1;
3699}
3700
3701////////////////////////////////////////////////////////////////////////////////
3702/// Load a macro file in cling's memory.
3703
3704void TCling::LoadMacro(const char* filename, EErrorCode* error)
3705{
3706 ProcessLine(Form(".L %s", filename), error);
3707}
3708
3709////////////////////////////////////////////////////////////////////////////////
3710/// Let cling process a command line asynch.
3711
3713{
3714 return ProcessLine(line, error);
3715}
3716
3717////////////////////////////////////////////////////////////////////////////////
3718/// Let cling process a command line synchronously, i.e we are waiting
3719/// it will be finished.
3720
3722{
3724 if (gApplication) {
3725 if (gApplication->IsCmdThread()) {
3726 return ProcessLine(line, error);
3727 }
3728 return 0;
3729 }
3730 return ProcessLine(line, error);
3731}
3732
3733////////////////////////////////////////////////////////////////////////////////
3734/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3735/// however not declarations, like "Int_t x;").
3736
3738{
3739#ifdef R__WIN32
3740 // Test on ApplicationImp not being 0 is needed because only at end of
3741 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3742 // we can not use it.
3744 while (gROOT->IsLineProcessing() && !gApplication) {
3745 Warning("Calc", "waiting for cling thread to free");
3746 gSystem->Sleep(500);
3747 }
3748 gROOT->SetLineIsProcessing();
3749 }
3750#endif // R__WIN32
3752 if (error) {
3753 *error = TInterpreter::kNoError;
3754 }
3755 cling::Value valRef;
3756 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3757 try {
3758 cr = fInterpreter->evaluate(line, valRef);
3759 }
3760 catch (cling::InterpreterException& ex)
3761 {
3762 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3763 ex.diagnose();
3764 cr = cling::Interpreter::kFailure;
3765 }
3766
3767 if (cr != cling::Interpreter::kSuccess) {
3768 // Failure in compilation.
3769 if (error) {
3770 // Note: Yes these codes are weird.
3772 }
3773 return 0L;
3774 }
3775 if (!valRef.isValid()) {
3776 // Failure at runtime.
3777 if (error) {
3778 // Note: Yes these codes are weird.
3779 *error = TInterpreter::kDangerous;
3780 }
3781 return 0L;
3782 }
3783
3784 if (valRef.isVoid()) {
3785 return 0;
3786 }
3787
3788 RegisterTemporary(valRef);
3789#ifdef R__WIN32
3791 gROOT->SetLineHasBeenProcessed();
3792 }
3793#endif // R__WIN32
3794 return valRef.castAs<Longptr_t>();
3795}
3796
3797////////////////////////////////////////////////////////////////////////////////
3798/// Set a getline function to call when input is needed.
3799
3800void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3801 void (*histaddFunc)(const char* line))
3802{
3803 // If cling offers a replacement for G__pause(), it would need to
3804 // also offer a way to customize at least the history recording.
3805
3806#if defined(R__MUST_REVISIT)
3807#if R__MUST_REVISIT(6,2)
3808 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3809#endif
3810#endif
3811}
3812
3813////////////////////////////////////////////////////////////////////////////////
3814/// Helper function to increase the internal Cling count of transactions
3815/// that change the AST.
3816
3817Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3818{
3820
3821 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3822 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3823 || T.macros_begin() != T.macros_end()
3824 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3826 return true;
3827 }
3828 return false;
3829}
3830
3831////////////////////////////////////////////////////////////////////////////////
3832/// Delete object from cling symbol table so it can not be used anymore.
3833/// cling objects are always on the heap.
3834
3836{
3837 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3838 // put in place the Read/Write part here. Keeping the write lock
3839 // here is 'catasptrophic' for scaling as it means that ALL calls
3840 // to RecursiveRemove will take the write lock and performance
3841 // of many threads trying to access the write lock at the same
3842 // time is relatively bad.
3844 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3845 // (but isn't at the moment).
3846 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3847 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3848 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3850 DeleteGlobal(obj);
3851 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3852 }
3853 }
3854}
3855
3856////////////////////////////////////////////////////////////////////////////////
3857/// Pressing Ctrl+C should forward here. In the case where we have had
3858/// continuation requested we must reset it.
3859
3861{
3862 fMetaProcessor->cancelContinuation();
3863 // Reset the Cling state to the state saved by the last call to
3864 // TCling::SaveContext().
3865#if defined(R__MUST_REVISIT)
3866#if R__MUST_REVISIT(6,2)
3868 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3869#endif
3870#endif
3871}
3872
3873////////////////////////////////////////////////////////////////////////////////
3874/// Reset the Cling state to its initial state.
3875
3877{
3878#if defined(R__MUST_REVISIT)
3879#if R__MUST_REVISIT(6,2)
3881 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3882#endif
3883#endif
3884}
3885
3886////////////////////////////////////////////////////////////////////////////////
3887/// Reset in Cling the list of global variables to the state saved by the last
3888/// call to TCling::SaveGlobalsContext().
3889///
3890/// Note: Right now, all we do is run the global destructors.
3891
3893{
3895 // TODO:
3896 // Here we should iterate over the transactions (N-3) and revert.
3897 // N-3 because the first three internal to cling.
3898
3899 fInterpreter->runAndRemoveStaticDestructors();
3900}
3901
3902////////////////////////////////////////////////////////////////////////////////
3903/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3904/// call to TCling::SaveGlobalsContext().
3905
3907{
3908#if defined(R__MUST_REVISIT)
3909#if R__MUST_REVISIT(6,2)
3911 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3912#endif
3913#endif
3914}
3915
3916////////////////////////////////////////////////////////////////////////////////
3917/// Rewind Cling dictionary to the point where it was before executing
3918/// the current macro. This function is typically called after SEGV or
3919/// ctlr-C after doing a longjmp back to the prompt.
3920
3922{
3923#if defined(R__MUST_REVISIT)
3924#if R__MUST_REVISIT(6,2)
3926 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3927#endif
3928#endif
3929}
3930
3931////////////////////////////////////////////////////////////////////////////////
3932/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3933/// Returns 1 in case of success and 0 in case object was not in table.
3934
3936{
3937#if defined(R__MUST_REVISIT)
3938#if R__MUST_REVISIT(6,2)
3940 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3941#endif
3942#endif
3943 return 0;
3944}
3945
3946////////////////////////////////////////////////////////////////////////////////
3947/// Undeclare obj called name.
3948/// Returns 1 in case of success, 0 for failure.
3949
3951{
3952#if defined(R__MUST_REVISIT)
3953#if R__MUST_REVISIT(6,2)
3954 Warning("DeleteVariable","should do more that just reseting the value to zero");
3955#endif
3956#endif
3957
3959 llvm::StringRef srName(name);
3960 const char* unscopedName = name;
3961 llvm::StringRef::size_type posScope = srName.rfind("::");
3962 const clang::DeclContext* declCtx = nullptr;
3963 if (posScope != llvm::StringRef::npos) {
3964 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3965 const clang::Decl* scopeDecl
3966 = lh.findScope(srName.substr(0, posScope),
3967 cling::LookupHelper::WithDiagnostics);
3968 if (!scopeDecl) {
3969 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3970 name);
3971 return 0;
3972 }
3973 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3974 if (!declCtx) {
3975 Error("DeleteVariable",
3976 "Enclosing scope for variable %s is not a declaration context",
3977 name);
3978 return 0;
3979 }
3980 unscopedName += posScope + 2;
3981 }
3982 // Could trigger deserialization of decls.
3983 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3984 clang::NamedDecl* nVarDecl
3985 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3986 if (!nVarDecl) {
3987 Error("DeleteVariable", "Unknown variable %s", name);
3988 return 0;
3989 }
3990 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3991 if (!varDecl) {
3992 Error("DeleteVariable", "Entity %s is not a variable", name);
3993 return 0;
3994 }
3995
3996 clang::QualType qType = varDecl->getType();
3997 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3998 // Cannot set a reference's address to nullptr; the JIT can place it
3999 // into read-only memory (ROOT-7100).
4000 if (type->isPointerType()) {
4001 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
4002 // set pointer to invalid.
4003 if (ppInt) *ppInt = nullptr;
4004 }
4005 return 1;
4006}
4007
4008////////////////////////////////////////////////////////////////////////////////
4009/// Save the current Cling state.
4010
4012{
4013#if defined(R__MUST_REVISIT)
4014#if R__MUST_REVISIT(6,2)
4016 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
4017#endif
4018#endif
4019}
4020
4021////////////////////////////////////////////////////////////////////////////////
4022/// Save the current Cling state of global objects.
4023
4025{
4026#if defined(R__MUST_REVISIT)
4027#if R__MUST_REVISIT(6,2)
4029 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
4030#endif
4031#endif
4032}
4033
4034////////////////////////////////////////////////////////////////////////////////
4035/// No op: see TClingCallbacks (used to update the list of globals)
4036
4040
4041////////////////////////////////////////////////////////////////////////////////
4042/// No op: see TClingCallbacks (used to update the list of global functions)
4043
4047
4048////////////////////////////////////////////////////////////////////////////////
4049/// No op: see TClingCallbacks (used to update the list of types)
4050
4052{
4053}
4054
4055////////////////////////////////////////////////////////////////////////////////
4056/// Check in what order the member of a tuple are layout.
4057enum class ETupleOrdering {
4058 kAscending,
4061};
4062
4068
4074
4076{
4077 std::tuple<int,double> value;
4080
4081 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
4082 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
4083
4084 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
4085 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
4086
4087 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
4088 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
4089
4090 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
4092 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
4094 } else {
4096 }
4097}
4098
4099static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
4100{
4101 TClassEdit::TSplitType tupleContent(classname);
4102 std::string alternateName = "TEmulatedTuple";
4103 alternateName.append( classname + 5 );
4104
4105 std::string fullname = "ROOT::Internal::" + alternateName;
4106 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
4107 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4108 return fullname;
4109
4110 {
4111 // Check if we can produce the tuple
4112 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4113 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4114 auto deleter = [](TypeInfo_t *type) {
4115 gInterpreter->TypeInfo_Delete(type);
4116 };
4117 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4118 while (iter != theEnd) {
4119 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4120 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4121 if (!silent)
4122 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4123 classname, iter->c_str());
4124 return "";
4125 }
4126 ++iter;
4127 }
4128 }
4129
4130 std::string guard_name;
4131 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
4132 std::ostringstream guard;
4133 guard << "ROOT_INTERNAL_TEmulated_";
4134 guard << guard_name;
4135
4136 std::ostringstream alternateTuple;
4137 std::ostringstream initializers;
4138
4139 alternateTuple << "#ifndef " << guard.str() << "\n";
4140 alternateTuple << "#define " << guard.str() << "\n";
4141 alternateTuple << "namespace ROOT { namespace Internal {\n";
4142 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4143 alternateTuple << "template <> struct " << alternateName << " {\n";
4144
4145 // This could also be a compile time choice ...
4146 switch(IsTupleAscending()) {
4148 unsigned int nMember = 0;
4149 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4150 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4151 auto sep = ':';
4152 while (iter != theEnd) {
4153 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4154 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4155 ++iter;
4156 ++nMember;
4157 sep = ',';
4158 }
4159 break;
4160 }
4162 unsigned int nMember = tupleContent.fElements.size() - 3;
4163 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4164 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4165 auto sep = ':';
4166 while (iter != theEnd) {
4167 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4168 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4169 ++iter;
4170 --nMember;
4171 sep = ',';
4172 }
4173 break;
4174 }
4176 Fatal("TCling::SetClassInfo::AlternateTuple",
4177 "Layout of std::tuple on this platform is unexpected.");
4178 break;
4179 }
4180 }
4181
4182 // default constructor
4183 alternateTuple << " TEmulatedTuple() = default;\n";
4184
4185 // constructor from other tuple-like types, like std::tuple
4186 alternateTuple << " template <typename Tuple>\n";
4187 alternateTuple << " TEmulatedTuple(Tuple&& t)\n";
4188 alternateTuple << initializers.str();
4189 alternateTuple << " {}\n";
4190
4191 alternateTuple << "};\n";
4192 alternateTuple << "}}\n";
4193 alternateTuple << "#endif\n";
4194 if (!gCling->Declare(alternateTuple.str().c_str()))
4195 {
4196 // Declare is not silent (yet?), so add an explicit error message
4197 // to indicate the consequence of the syntax errors.
4198 Error("Load","Could not declare %s",alternateName.c_str());
4199 return "";
4200 }
4201 alternateName = "ROOT::Internal::" + alternateName;
4202 return alternateName;
4203}
4204
4205////////////////////////////////////////////////////////////////////////////////
4206/// Set pointer to the TClingClassInfo in TClass.
4207/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4208/// already have one.
4209/// If 'classInfo' is non-null, take ownership of it and use it instead of
4210/// looking up the class again; it must have been obtained from a call to
4211/// CheckClassInfo(cl->GetName(), ...).
4212
4213void TCling::SetClassInfo(TClass *cl, Bool_t reload, Bool_t silent, ClassInfo_t *classInfo)
4214{
4215 // Whether we use it below or not, we own the passed class info.
4216 std::unique_ptr<TClingClassInfo> providedInfo{(TClingClassInfo *)classInfo};
4217
4218 // A provided class info is a cached lookup result; honoring it would defeat
4219 // the point of a reload, which is to redo the lookup.
4220 if (reload)
4221 providedInfo.reset();
4222
4223 // We are shutting down, there is no point in reloading, it only triggers
4224 // redundant deserializations.
4225 if (fIsShuttingDown) {
4226 // Remove the decl_id from the DeclIdToTClass map
4227 if (cl->fClassInfo) {
4229 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4230 // Test again as another thread may have set fClassInfo to nullptr.
4231 if (TClinginfo) {
4232 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4233 }
4234 delete TClinginfo;
4235 cl->fClassInfo = nullptr;
4236 }
4237 return;
4238 }
4239
4241 if (cl->fClassInfo && !reload) {
4242 return;
4243 }
4244 //Remove the decl_id from the DeclIdToTClass map
4245 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4246 if (TClinginfo) {
4247 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4248 }
4249 delete TClinginfo;
4250 cl->fClassInfo = nullptr;
4251 std::string name(cl->GetName());
4252
4253 auto SetWithoutClassInfoState = [](TClass *cl)
4254 {
4255 if (cl->fState != TClass::kHasTClassInit) {
4256 if (cl->fStreamerInfo->GetEntries() != 0) {
4258 } else {
4260 }
4261 }
4262 };
4263 // Handle the special case of 'tuple' where we ignore the real implementation
4264 // details and just overlay a 'simpler'/'simplistic' version that is easy
4265 // for the I/O to understand and handle.
4266 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4267 // A provided class info would describe the real std::tuple, not the
4268 // alternate version overlaid below: it cannot be used.
4269 providedInfo.reset();
4270 if (!reload)
4271 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4272 if (reload || name.empty()) {
4273 // We could not generate the alternate
4274 SetWithoutClassInfoState(cl);
4275 return;
4276 }
4277 }
4278
4279 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4280 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4281 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4282 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4283 // TClingClassInfoReadOnly.
4284 TClingClassInfo *info = providedInfo ? providedInfo.release()
4285 : new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4286 if (!info->IsValid()) {
4287 SetWithoutClassInfoState(cl);
4288 delete info;
4289 return;
4290 }
4291 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4292 // In case a class contains an external enum, the enum will be seen as a
4293 // class. We must detect this special case and make the class a Zombie.
4294 // Here we assume that a class has at least one method.
4295 // We can NOT call TClass::Property from here, because this method
4296 // assumes that the TClass is well formed to do a lot of information
4297 // caching. The method SetClassInfo (i.e. here) is usually called during
4298 // the building phase of the TClass, hence it is NOT well formed yet.
4299 Bool_t zombieCandidate = kFALSE;
4300 if (
4301 info->IsValid() &&
4302 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4303 ) {
4304 zombieCandidate = kTRUE;
4305 }
4306 if (!info->IsLoaded()) {
4307 if (info->Property() & (kIsNamespace)) {
4308 // Namespaces can have info but no corresponding CINT dictionary
4309 // because they are auto-created if one of their contained
4310 // classes has a dictionary.
4311 zombieCandidate = kTRUE;
4312 }
4313 // this happens when no dictionary is available
4314 delete info;
4315 cl->fClassInfo = nullptr;
4316 }
4317 if (zombieCandidate && !cl->GetCollectionType()) {
4318 cl->MakeZombie();
4319 }
4320 // If we reach here, the info was valid (See early returns).
4321 if (cl->fState != TClass::kHasTClassInit) {
4322 if (cl->fClassInfo) {
4324 } else {
4325// if (TClassEdit::IsSTLCont(cl->GetName()) {
4326// There will be an emulated collection proxy, is that the same?
4327// cl->fState = TClass::kEmulated;
4328// } else {
4329 if (cl->fStreamerInfo->GetEntries() != 0) {
4331 } else {
4333 }
4334// }
4335 }
4336 }
4337 if (cl->fClassInfo) {
4338 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4339 }
4340}
4341
4342////////////////////////////////////////////////////////////////////////////////
4343/// Checks if an entity with the specified name is defined in Cling.
4344/// Returns kUnknown if the entity is not defined.
4345/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4346/// Returns kKnown if the entity is defined.
4347///
4348/// By default, structs, namespaces, classes, enums and unions are looked for.
4349/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4350/// namespaces only are considered. I.e. if the name is an enum or a union,
4351/// the returned value is false.
4352///
4353/// In the case where the class is not loaded and belongs to a namespace
4354/// or is nested, looking for the full class name is outputting a lots of
4355/// (expected) error messages. Currently the only way to avoid this is to
4356/// specifically check that each level of nesting is already loaded.
4357/// In case of templates the idea is that everything between the outer
4358/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4359///
4360/// If 'classInfo' is non-null and the lookup found a declaration (which
4361/// findScope only returns if it points to a complete definition, i.e. when no
4362/// template instantiation would be needed to create it), '*classInfo' is set
4363/// to a newly allocated TClingClassInfo for that declaration, owned by the
4364/// caller. Passing it to SetClassInfo() avoids repeating the lookup there.
4365
4367 Bool_t isClassOrNamespaceOnly /* = kFALSE*/,
4368 ClassInfo_t **classInfo /* = nullptr*/)
4369{
4371 if (classInfo)
4372 *classInfo = nullptr;
4373 static const char *anonEnum = "anonymous enum ";
4374 static const int cmplen = strlen(anonEnum);
4375
4376 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4377 return kUnknown;
4378 }
4379
4380 // Do not turn on the AutoLoading if it is globally off.
4381 autoload = autoload && IsClassAutoLoadingEnabled();
4382
4383 // Avoid the double search below in case the name is a fundamental type
4384 // or typedef to a fundamental type.
4385 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4386 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4387
4388 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4389 && fundType->GetType() > 0) {
4390 // Fundamental type, no a class.
4391 return kUnknown;
4392 }
4393
4394 // Migrated from within TClass::GetClass
4395 // If we want to know if a class or a namespace with this name exists in the
4396 // interpreter and this is an enum in the type system, before or after loading
4397 // according to the autoload function argument, return kUnknown.
4398 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4399 return kUnknown;
4400
4401 const char *classname = name;
4402
4403 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4404 class MaybeSuspendAutoLoadParse {
4405 int fStoreAutoLoad = 0;
4406 int fStoreAutoParse = 0;
4407 bool fSuspendedAutoParse = false;
4408 public:
4409 MaybeSuspendAutoLoadParse(int autoload) {
4410 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4411 }
4412
4413 void SuspendAutoParsing() {
4414 fSuspendedAutoParse = true;
4415 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4416 }
4417
4418 ~MaybeSuspendAutoLoadParse() {
4419 if (fSuspendedAutoParse)
4420 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4421 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4422 }
4423 };
4424
4425 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4426 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4427 autoLoadParseRAII.SuspendAutoParsing();
4428
4429 // First we want to check whether the decl exist, but _without_
4430 // generating any template instantiation. However, the lookup
4431 // still will create a forward declaration of the class template instance
4432 // if it exist. In this case, the return value of findScope will still
4433 // be zero but the type will be initialized.
4434 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4435 // this forward declaration.
4436 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4437 const clang::Type *type = nullptr;
4438 const clang::Decl *decl
4439 = lh.findScope(classname,
4440 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4441 : cling::LookupHelper::NoDiagnostics,
4442 &type, /* intantiateTemplate= */ false );
4443 if (!decl) {
4444 // Use a separate output type for the retry: findScope does not write it
4445 // on every path (e.g. when finding a namespace), and the type left over
4446 // from the lookup above must not be paired with this lookup's decl.
4447 const clang::Type *typeFromStd = nullptr;
4448 std::string buf = TClassEdit::InsertStd(classname);
4449 decl = lh.findScope(buf, gDebug > 5 ? cling::LookupHelper::WithDiagnostics : cling::LookupHelper::NoDiagnostics,
4450 &typeFromStd, false);
4451 if (decl || typeFromStd)
4452 type = typeFromStd;
4453 }
4454
4455 // If requested and an entity was found by the lookup above, hand a class
4456 // info for it out to the caller (see the function documentation).
4457 auto provideClassInfo = [this, classInfo, &decl, &type] {
4458 if (classInfo && decl && !decl->isInvalidDecl())
4459 *classInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), decl, type);
4460 };
4461
4462 if (type) {
4463 // If decl==0 and the type is valid, then we have a forward declaration.
4464 if (!decl) {
4465 // If we have a forward declaration for a class template instantiation,
4466 // we want to ignore it if it was produced/induced by the call to
4467 // findScope, however we can not distinguish those from the
4468 // instantiation induce by 'soft' use (and thus also induce by the
4469 // same underlying code paths)
4470 // ['soft' use = use not requiring a complete definition]
4471 // So to reduce the amount of disruption to the existing code we
4472 // would just ignore those for STL collection, for which we really
4473 // need to have the compiled collection proxy (and thus the TClass
4474 // bootstrap).
4475 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4476 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4477 (type->getAsCXXRecordDecl());
4478 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4479 // Since the point of instantiation is invalid, we 'guess' that
4480 // the 'instantiation' of the forwarded type appended in
4481 // findscope.
4482 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4483 // For STL Collection we return kUnknown.
4484 return kUnknown;
4485 }
4486 }
4487 }
4489 if (!tci.IsValid()) {
4490 return kUnknown;
4491 }
4492 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4494
4495 if (tci.Property() & propertiesMask) {
4496 bool hasClassDefInline = false;
4497 if (isClassOrNamespaceOnly) {
4498 // We do not need to check for ClassDefInline when this is called from
4499 // TClass::Init, we only do it for the call from TClass::GetClass.
4500 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4501 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4502
4503 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4504 int lineNumber = 0;
4505 bool success = false;
4506 std::tie(success, lineNumber) =
4507 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4508 hasClassDefInline = success && (lineNumber == -1);
4509 }
4510 }
4511
4512 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4513 // , hasClassDefInline);
4514
4515 // We are now sure that the entry is not in fact an autoload entry.
4516 provideClassInfo();
4517 if (hasClassDefInline)
4518 return kWithClassDefInline;
4519 else
4520 return kKnown;
4521 } else {
4522 // We are now sure that the entry is not in fact an autoload entry.
4523 return kUnknown;
4524 }
4525 }
4526
4527 if (decl) {
4528 provideClassInfo();
4529 return kKnown;
4530 } else
4531 return kUnknown;
4532
4533 // Setting up iterator part of TClingTypedefInfo is too slow.
4534 // Copy the lookup code instead:
4535 /*
4536 TClingTypedefInfo t(fInterpreter, name);
4537 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4538 delete[] classname;
4539 return kTRUE;
4540 }
4541 */
4542
4543// const clang::Decl *decl = lh.findScope(name);
4544// if (!decl) {
4545// std::string buf = TClassEdit::InsertStd(name);
4546// decl = lh.findScope(buf);
4547// }
4548
4549// return (decl);
4550}
4551
4552////////////////////////////////////////////////////////////////////////////////
4553/// Return true if there is a class template by the given name ...
4554
4556{
4557 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4558 // Interpreter transaction ahead, needs locking
4560 const clang::Decl *decl
4561 = lh.findClassTemplate(name,
4562 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4563 : cling::LookupHelper::NoDiagnostics);
4564 if (!decl) {
4565 std::string strname = "std::";
4566 strname += name;
4567 decl = lh.findClassTemplate(strname,
4568 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4569 : cling::LookupHelper::NoDiagnostics);
4570 }
4571 return nullptr != decl;
4572}
4573
4574////////////////////////////////////////////////////////////////////////////////
4575/// Create list of pointers to base class(es) for TClass cl.
4576
4578{
4580 if (cl->fBase) {
4581 return;
4582 }
4583 // Ignore the base class (e.g. `std::_Complex_base` on Windows)
4585 cl->fBase = new TList();
4586 return;
4587 }
4589 if (!tci) return;
4591 TList *listOfBase = new TList;
4592 while (t.Next()) {
4593 // if name cannot be obtained no use to put in list
4594 if (t.IsValid() && t.Name()) {
4596 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4597 }
4598 }
4599 // Now that is complete, publish it.
4600 cl->fBase = listOfBase;
4601}
4602
4603////////////////////////////////////////////////////////////////////////////////
4604/// Create list of pointers to enums for TClass cl.
4605
4606void TCling::LoadEnums(TListOfEnums& enumList) const
4607{
4609
4610 const Decl * D;
4611 TClass* cl = enumList.GetClass();
4612 if (cl) {
4613 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4614 }
4615 else {
4616 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4617 }
4618 // Iterate on the decl of the class and get the enums.
4619 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4620 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4621 // Collect all contexts of the namespace.
4622 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4623 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4624 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4625 declIter != declEnd; ++declIter) {
4626 // Iterate on all decls for each context.
4627 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4628 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4629 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4630 // Get name of the enum type.
4631 std::string buf;
4632 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4633 llvm::raw_string_ostream stream(buf);
4634 // Don't trigger fopen of the source file to count lines:
4635 Policy.AnonymousTagLocations = false;
4636 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4637 stream.flush();
4638 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4639 if (!buf.empty()) {
4640 const char* name = buf.c_str();
4641 // Add the enum to the list of loaded enums.
4642 enumList.Get(ED, name);
4643 }
4644 }
4645 }
4646 }
4647 }
4648}
4649
4650////////////////////////////////////////////////////////////////////////////////
4651/// Create list of pointers to function templates for TClass cl.
4652
4654{
4656
4657 const Decl * D;
4658 TListOfFunctionTemplates* funcTempList;
4659 if (cl) {
4660 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4661 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4662 }
4663 else {
4664 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4665 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4666 }
4667 // Iterate on the decl of the class and get the enums.
4668 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4669 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4670 // Collect all contexts of the namespace.
4671 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4672 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4673 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4674 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4675 // Iterate on all decls for each context.
4676 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4677 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4678 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4679 funcTempList->Get(FTD);
4680 }
4681 }
4682 }
4683 }
4684}
4685
4686////////////////////////////////////////////////////////////////////////////////
4687/// Get the scopes representing using declarations of namespace
4688
4689std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4690{
4692 return ci->GetUsingNamespaces();
4693}
4694
4695////////////////////////////////////////////////////////////////////////////////
4696/// Create list of pointers to data members for TClass cl.
4697/// This is now a nop. The creation and updating is handled in
4698/// TListOfDataMembers.
4699
4701{
4702}
4703
4704////////////////////////////////////////////////////////////////////////////////
4705/// Create list of pointers to methods for TClass cl.
4706/// This is now a nop. The creation and updating is handled in
4707/// TListOfFunctions.
4708
4710{
4711}
4712
4713////////////////////////////////////////////////////////////////////////////////
4714/// Update the list of pointers to method for TClass cl
4715/// This is now a nop. The creation and updating is handled in
4716/// TListOfFunctions.
4717
4719{
4720}
4721
4722////////////////////////////////////////////////////////////////////////////////
4723/// Update the list of pointers to data members for TClass cl
4724/// This is now a nop. The creation and updating is handled in
4725/// TListOfDataMembers.
4726
4728{
4729}
4730
4731////////////////////////////////////////////////////////////////////////////////
4732/// Create list of pointers to method arguments for TMethod m.
4733
4735{
4737 if (m->fMethodArgs) {
4738 return;
4739 }
4740 TList *arglist = new TList;
4742 while (t.Next()) {
4743 if (t.IsValid()) {
4745 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4746 }
4747 }
4748 m->fMethodArgs = arglist;
4749}
4750
4751////////////////////////////////////////////////////////////////////////////////
4752/// Return whether we are waiting for more input either because the collected
4753/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4754
4756{
4757 return fMetaProcessor->awaitingMoreInput();
4758}
4759
4760////////////////////////////////////////////////////////////////////////////////
4761/// Generate a TClass for the given class.
4762/// Since the caller has already check the ClassInfo, let it give use the
4763/// result (via the value of emulation) rather than recalculate it.
4764
4765TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4766{
4767// For now the following line would lead to the (unwanted) instantiation
4768// of class template. This could/would need to be resurrected only if
4769// we re-introduce so sort of automatic instantiation. However this would
4770// have to include carefull look at the template parameter to avoid
4771// creating instance we can not really use (if the parameter are only forward
4772// declaration or do not have all the necessary interfaces).
4773
4774 // TClingClassInfo tci(fInterpreter, classname);
4775 // if (1 || !tci.IsValid()) {
4776
4777 Version_t version = 1;
4778 if (TClassEdit::IsSTLCont(classname)) {
4779 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4780 }
4782 TClass *cl = new TClass(classname, version, silent);
4783 if (!emulation) {
4784 // Set the class version if the class is versioned.
4785 // Note that we cannot just call CLASS::Class_Version() as we might not have
4786 // an execution engine (when invoked from rootcling).
4787
4788 // Do not call cl->GetClassVersion(), it has side effects!
4789 Version_t oldvers = cl->fClassVersion;
4790 if (oldvers == version && cl->GetClassInfo()) {
4791 // We have a version and it might need an update.
4793 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4794 // Namespaces don't have class versions.
4795 return cl;
4796 }
4797 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4800 if (!mi.IsValid()) {
4801 if (cl->TestBit(TClass::kIsTObject)) {
4802 Error("GenerateTClass",
4803 "Cannot find %s::Class_Version()! Class version might be wrong.",
4804 cl->GetName());
4805 }
4806 return cl;
4807 }
4808 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4809 *fInterpreter);
4810 if (newvers == -1) {
4811 // Didn't manage to determine the class version from the AST.
4812 // Use runtime instead.
4813 if ((mi.Property() & kIsStatic)
4814 && !fInterpreter->isInSyntaxOnlyMode()) {
4815 // This better be a static function.
4817 callfunc.SetFunc(&mi);
4818 newvers = callfunc.ExecInt(nullptr);
4819 } else {
4820 Error("GenerateTClass",
4821 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4822 cl->GetName());
4823 }
4824 }
4825 if (newvers != oldvers) {
4826 cl->fClassVersion = newvers;
4827 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4828 }
4829 }
4830 }
4831
4832 return cl;
4833
4834// } else {
4835// return GenerateTClass(&tci,silent);
4836// }
4837}
4838
4839#if 0
4840////////////////////////////////////////////////////////////////////////////////
4841
4842static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4843{
4844 includes += info->FileName();
4845
4846 const clang::ClassTemplateSpecializationDecl *templateCl
4847 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4848 if (templateCl) {
4849 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4850 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4851 if (arg.getKind() == clang::TemplateArgument::Type) {
4852 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4853
4854 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4855 // We really need a header file.
4856 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4857 if (argdecl) {
4858 includes += ";";
4859 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4860 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4861 } else {
4862 std::string Result;
4863 llvm::raw_string_ostream OS(Result);
4864 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4865 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4866 }
4867 }
4868 }
4869 }
4870 }
4871}
4872#endif
4873
4874////////////////////////////////////////////////////////////////////////////////
4875/// Generate a TClass for the given class.
4876
4877TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4878{
4879 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4880 if (!info || !info->IsValid()) {
4881 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4882 return nullptr;
4883 }
4884 // We are in the case where we have AST nodes for this class.
4885 TClass *cl = nullptr;
4886 std::string classname;
4887 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4888 if (TClassEdit::IsSTLCont(classname)) {
4889#if 0
4890 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4891 // We need to build up the list of required headers, by
4892 // looking at each template arguments.
4893 TString includes;
4894 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4895
4896 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4897 // 0 means success.
4898 cl = TClass::LoadClass(classnam.c_str(), silent);
4899 if (cl == 0) {
4900 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4901 }
4902 }
4903#endif
4904 if (cl == nullptr) {
4905 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4906 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4907 }
4908 } else {
4909 // For regular class, just create a TClass on the fly ...
4910 // Not quite useful yet, but that what CINT used to do anyway.
4911 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4912 }
4913 // Add the new TClass to the map of declid and TClass*.
4914 if (cl) {
4916 }
4917 return cl;
4918}
4919
4920////////////////////////////////////////////////////////////////////////////////
4921/// Generate the dictionary for the C++ classes listed in the first
4922/// argument (in a semi-colon separated list).
4923/// 'includes' contains a semi-colon separated list of file to
4924/// `#include` in the dictionary.
4925/// For example:
4926/// ~~~ {.cpp}
4927/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4928/// ~~~
4929/// or
4930/// ~~~ {.cpp}
4931/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4932/// ~~~
4933
4934Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4935{
4936 if (classes == nullptr || classes[0] == 0) {
4937 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4938 return 0;
4939 }
4940 // Split the input list
4941 std::vector<std::string> listClasses;
4942 for (
4943 const char* current = classes, *prev = classes;
4944 *current != 0;
4945 ++current
4946 ) {
4947 if (*current == ';') {
4948 listClasses.push_back(std::string(prev, current - prev));
4949 prev = current + 1;
4950 }
4951 else if (*(current + 1) == 0) {
4952 listClasses.push_back(std::string(prev, current + 1 - prev));
4953 prev = current + 1;
4954 }
4955 }
4956 std::vector<std::string> listIncludes;
4957 if (!includes)
4958 includes = "";
4959 for (
4960 const char* current = includes, *prev = includes;
4961 *current != 0;
4962 ++current
4963 ) {
4964 if (*current == ';') {
4965 listIncludes.push_back(std::string(prev, current - prev));
4966 prev = current + 1;
4967 }
4968 else if (*(current + 1) == 0) {
4969 listIncludes.push_back(std::string(prev, current + 1 - prev));
4970 prev = current + 1;
4971 }
4972 }
4973 // Generate the temporary dictionary file
4974 return !TCling_GenerateDictionary(listClasses, listIncludes,
4975 std::vector<std::string>(), std::vector<std::string>());
4976}
4977
4978////////////////////////////////////////////////////////////////////////////////
4979/// Return pointer to cling Decl of global/static variable that is located
4980/// at the address given by addr.
4981
4982TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4983{
4985 DeclId_t d;
4986 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4987
4988 // Could trigger deserialization of decls.
4989 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4990
4991 if (cl) {
4992 d = cl->GetDataMember(name);
4993 // We check if the decl of the data member has an annotation which indicates
4994 // an ioname.
4995 // In case this is true, if the name requested is not the ioname, we
4996 // return 0, as if the member did not exist. In some sense we override
4997 // the information in the TClassInfo instance, isolating the typesystem in
4998 // TClass from the one in the AST.
4999 if (const ValueDecl* decl = (const ValueDecl*) d){
5000 std::string ioName;
5001 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
5002 if (hasIoName && ioName != name) return nullptr;
5003 }
5004 return d;
5005 }
5006 // We are looking up for something on the TU scope.
5007 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
5008 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
5009 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
5010 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
5011 // are only fulfilling ROOT's understanding for a Data Member.
5012 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
5013 // similar as below.
5014 using namespace clang;
5015 Sema& SemaR = fInterpreter->getSema();
5016 DeclarationName DName = &SemaR.Context.Idents.get(name);
5017
5018 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
5019 RedeclarationKind::ForExternalRedeclaration);
5020
5021 cling::utils::Lookup::Named(&SemaR, R);
5022
5023 LookupResult::Filter F = R.makeFilter();
5024 // Filter the data-member looking decls.
5025 while (F.hasNext()) {
5026 NamedDecl *D = F.next();
5027 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
5028 isa<IndirectFieldDecl>(D))
5029 continue;
5030 F.erase();
5031 }
5032 F.done();
5033
5034 if (R.isSingleResult())
5035 return R.getFoundDecl();
5036 return nullptr;
5037}
5038
5039////////////////////////////////////////////////////////////////////////////////
5040/// Return pointer to cling Decl of global/static variable that is located
5041/// at the address given by addr.
5042
5044{
5046
5047 const clang::Decl* possibleEnum = nullptr;
5048 // FInd the context of the decl.
5049 if (cl) {
5051 if (cci) {
5052 const clang::DeclContext* dc = nullptr;
5053 if (const clang::Decl* D = cci->GetDecl()) {
5054 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
5055 dc = dyn_cast<clang::RecordDecl>(D);
5056 }
5057 }
5058 if (dc) {
5059 // If it is a data member enum.
5060 // Could trigger deserialization of decls.
5061 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5062 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
5063 } else {
5064 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
5065 }
5066 }
5067 } else {
5068 // If it is a global enum.
5069 // Could trigger deserialization of decls.
5070 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5071 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
5072 }
5073 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
5074 && isa<clang::EnumDecl>(possibleEnum)) {
5075 return possibleEnum;
5076 }
5077 return nullptr;
5078}
5079
5080////////////////////////////////////////////////////////////////////////////////
5081/// Return pointer to cling DeclId for a global value
5082
5083TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
5084{
5085 if (!gv) return nullptr;
5086
5087 llvm::StringRef mangled_name = gv->getName();
5088
5089 int err = 0;
5090 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
5091 if (err) {
5092 if (err == -2) {
5093 // It might simply be an unmangled global name.
5094 DeclId_t d;
5096 d = gcl.GetDataMember(mangled_name.str().c_str());
5097 return d;
5098 }
5099 return nullptr;
5100 }
5101
5102 std::string scopename(demangled_name_c);
5103 free(demangled_name_c);
5104
5105 //
5106 // Separate out the class or namespace part of the
5107 // function name.
5108 //
5109 std::string dataname;
5110
5111 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
5112 scopename.erase(0, sizeof("typeinfo for ")-1);
5113 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
5114 scopename.erase(0, sizeof("vtable for ")-1);
5115 } else {
5116 // See if it is a function
5117 std::string::size_type pos = scopename.rfind('(');
5118 if (pos != std::string::npos) {
5119 return nullptr;
5120 }
5121 // Separate the scope and member name
5122 pos = scopename.rfind(':');
5123 if (pos != std::string::npos) {
5124 if ((pos != 0) && (scopename[pos-1] == ':')) {
5125 dataname = scopename.substr(pos+1);
5126 scopename.erase(pos-1);
5127 }
5128 } else {
5129 scopename.clear();
5130 dataname = scopename;
5131 }
5132 }
5133 //fprintf(stderr, "name: '%s'\n", name.c_str());
5134 // Now we have the class or namespace name, so do the lookup.
5135
5136
5137 DeclId_t d;
5138 if (scopename.size()) {
5139 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
5140 d = cl.GetDataMember(dataname.c_str());
5141 }
5142 else {
5144 d = gcl.GetDataMember(dataname.c_str());
5145 }
5146 return d;
5147}
5148
5149////////////////////////////////////////////////////////////////////////////////
5150/// NOT IMPLEMENTED.
5151
5153{
5154 Error("GetDataMemberWithValue()", "not implemented");
5155 return nullptr;
5156}
5157
5158////////////////////////////////////////////////////////////////////////////////
5159/// Return pointer to cling DeclId for a data member with a given name.
5160
5162{
5163 // NOT IMPLEMENTED.
5164 Error("GetDataMemberAtAddr()", "not implemented");
5165 return nullptr;
5166}
5167
5168////////////////////////////////////////////////////////////////////////////////
5169/// Return the cling mangled name for a method of a class with parameters
5170/// params (params is a string of actual arguments, not formal ones). If the
5171/// class is 0 the global function list will be searched.
5172
5173TString TCling::GetMangledName(TClass* cl, const char* method,
5174 const char* params, Bool_t objectIsConst /* = kFALSE */)
5175{
5178 if (cl) {
5180 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5181 &offset);
5182 }
5183 else {
5186 func.SetFunc(&gcl, method, params, &offset);
5187 }
5189 if (!mi) return "";
5190 TString mangled_name( mi->GetMangledName() );
5191 delete mi;
5192 return mangled_name;
5193}
5194
5195////////////////////////////////////////////////////////////////////////////////
5196/// Return the cling mangled name for a method of a class with a certain
5197/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5198/// list will be searched.
5199
5201 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5202 EFunctionMatchMode mode /* = kConversionMatch */)
5203{
5205 if (cl) {
5206 return ((TClingClassInfo*)cl->GetClassInfo())->
5207 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5208 }
5210 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5211}
5212
5213////////////////////////////////////////////////////////////////////////////////
5214/// Return pointer to cling interface function for a method of a class with
5215/// parameters params (params is a string of actual arguments, not formal
5216/// ones). If the class is 0 the global function list will be searched.
5217
5218void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5219 const char* params, Bool_t objectIsConst /* = kFALSE */)
5220{
5223 if (cl) {
5225 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5226 &offset);
5227 }
5228 else {
5231 func.SetFunc(&gcl, method, params, &offset);
5232 }
5233 return (void*) func.InterfaceMethod();
5234}
5235
5236////////////////////////////////////////////////////////////////////////////////
5237/// Return pointer to cling interface function for a method of a class with
5238/// a certain name.
5239
5240TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5241{
5243 DeclId_t f;
5244 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5245 if (cl) {
5246 f = cl->GetMethod(method).GetDeclId();
5247 }
5248 else {
5250 f = gcl.GetMethod(method).GetDeclId();
5251 }
5252 return f;
5253
5254}
5255
5256////////////////////////////////////////////////////////////////////////////////
5257/// Insert overloads of name in cl to res.
5258
5259void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5260 std::vector<DeclId_t>& res) const
5261{
5262 clang::Sema& S = fInterpreter->getSema();
5263 clang::ASTContext& Ctx = S.Context;
5264 const clang::Decl* CtxDecl
5265 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5266 Ctx.getTranslationUnitDecl();
5267 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5268 const clang::DeclContext* DeclCtx = RecDecl;
5269
5270 if (!DeclCtx)
5271 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5272 if (!DeclCtx) return;
5273
5274 clang::DeclarationName DName;
5275 // The DeclarationName is funcname, unless it's a ctor or dtor.
5276 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5277
5278 if (RecDecl) {
5279 if (RecDecl->getNameAsString() == funcname) {
5280 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5281 DName = Ctx.DeclarationNames.getCXXConstructorName(QT);
5282 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5283 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5284 DName = Ctx.DeclarationNames.getCXXDestructorName(QT);
5285 } else {
5286 DName = &Ctx.Idents.get(funcname);
5287 }
5288 } else {
5289 DName = &Ctx.Idents.get(funcname);
5290 }
5291
5292 // NotForRedeclaration: we want to find names in inline namespaces etc.
5293 clang::LookupResult R(S, DName, clang::SourceLocation(), Sema::LookupOrdinaryName,
5294 RedeclarationKind::NotForRedeclaration);
5295 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5296 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5297 if (R.empty()) return;
5298 R.resolveKind();
5299 res.reserve(res.size() + (R.end() - R.begin()));
5300 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5301 IR != ER; ++IR) {
5302 if (const clang::FunctionDecl* FD
5303 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5304 if (!FD->getDescribedFunctionTemplate()) {
5305 res.push_back(FD);
5306 }
5307 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5308 // FIXME: multi-level using
5309 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5310 res.push_back(USD);
5311 }
5312 }
5313 }
5314}
5315
5316////////////////////////////////////////////////////////////////////////////////
5317/// Return pointer to cling interface function for a method of a class with
5318/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5319/// function list will be searched.
5320
5322 const char* proto,
5323 Bool_t objectIsConst /* = kFALSE */,
5324 EFunctionMatchMode mode /* = kConversionMatch */)
5325{
5327 void* f;
5328 if (cl) {
5329 f = ((TClingClassInfo*)cl->GetClassInfo())->
5330 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5331 }
5332 else {
5334 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5335 }
5336 return f;
5337}
5338
5339////////////////////////////////////////////////////////////////////////////////
5340/// Return pointer to cling DeclId for a method of a class with
5341/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5342/// function list will be searched.
5343
5344TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5345 const char* params,
5346 Bool_t objectIsConst /* = kFALSE */)
5347{
5349 DeclId_t f;
5350 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5351 if (cl) {
5352 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5353 }
5354 else {
5356 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5357 }
5358 return f;
5359}
5360
5361////////////////////////////////////////////////////////////////////////////////
5362/// Return pointer to cling interface function for a method of a class with
5363/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5364/// function list will be searched.
5365
5366TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5367 const char* proto,
5368 Bool_t objectIsConst /* = kFALSE */,
5369 EFunctionMatchMode mode /* = kConversionMatch */)
5370{
5372 DeclId_t f;
5373 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5374 if (cl) {
5375 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5376 }
5377 else {
5379 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5380 }
5381 return f;
5382}
5383
5384////////////////////////////////////////////////////////////////////////////////
5385/// Return pointer to cling interface function for a method of a class with
5386/// a certain name.
5387
5388TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5389{
5391 DeclId_t f;
5392 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5393 if (cl) {
5394 f = cl->GetFunctionTemplate(name);
5395 }
5396 else {
5398 f = gcl.GetFunctionTemplate(name);
5399 }
5400 return f;
5401
5402}
5403
5404////////////////////////////////////////////////////////////////////////////////
5405/// The 'name' is known to the interpreter, this function returns
5406/// the internal version of this name (usually just resolving typedefs)
5407/// This is used in particular to synchronize between the name used
5408/// by rootcling and by the run-time environment (TClass)
5409/// Return 0 if the name is not known.
5410
5411void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5412{
5413 output.clear();
5414
5416
5418 if (!cl.IsValid()) {
5419 return ;
5420 }
5421 if (full) {
5422 cl.FullName(output,*fNormalizedCtxt);
5423 return;
5424 }
5425 // Well well well, for backward compatibility we need to act a bit too
5426 // much like CINT.
5428 splitname.ShortType(output, TClassEdit::kDropStd );
5429
5430 return;
5431}
5432
5433////////////////////////////////////////////////////////////////////////////////
5434/// Execute a global function with arguments params.
5435///
5436/// FIXME: The cint-based version of this code does not check if the
5437/// SetFunc() call works, and does not do any real checking
5438/// for errors from the Exec() call. It did fetch the most
5439/// recent cint security error and return that in error, but
5440/// this does not really translate well to cling/clang. We
5441/// should enhance these interfaces so that we can report
5442/// compilation and runtime errors properly.
5443
5444void TCling::Execute(const char* function, const char* params, int* error)
5445{
5447 if (error) {
5448 *error = TInterpreter::kNoError;
5449 }
5451 Longptr_t offset = 0L;
5453 func.SetFunc(&cl, function, params, &offset);
5454 func.Exec(nullptr);
5455}
5456
5457////////////////////////////////////////////////////////////////////////////////
5458/// Execute a method from class cl with arguments params.
5459///
5460/// FIXME: The cint-based version of this code does not check if the
5461/// SetFunc() call works, and does not do any real checking
5462/// for errors from the Exec() call. It did fetch the most
5463/// recent cint security error and return that in error, but
5464/// this does not really translate well to cling/clang. We
5465/// should enhance these interfaces so that we can report
5466/// compilation and runtime errors properly.
5467
5468void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5469 const char* params, Bool_t objectIsConst, int* error)
5470{
5472 if (error) {
5473 *error = TInterpreter::kNoError;
5474 }
5475 // If the actual class of this object inherits 2nd (or more) from TObject,
5476 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5477 // hence gInterpreter->Execute will improperly correct the offset.
5478 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5479 Longptr_t offset = 0L;
5481 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5482 void* address = (void*)((Longptr_t)addr + offset);
5483 func.Exec(address);
5484}
5485
5486////////////////////////////////////////////////////////////////////////////////
5487
5488void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5489 const char* params, int* error)
5490{
5491 Execute(obj,cl,method,params,false,error);
5492}
5493
5494////////////////////////////////////////////////////////////////////////////////
5495/// Execute a method from class cl with the arguments in array params
5496/// (params[0] ... params[n] = array of TObjString parameters).
5497/// Convert the TObjArray array of TObjString parameters to a character
5498/// string of comma separated parameters.
5499/// The parameters of type 'char' are enclosed in double quotes and all
5500/// internal quotes are escaped.
5501
5502void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5503 TObjArray* params, int* error)
5504{
5505 if (!method) {
5506 Error("Execute", "No method was defined");
5507 return;
5508 }
5509 TList* argList = method->GetListOfMethodArgs();
5510 // Check number of actual parameters against of expected formal ones
5511
5512 Int_t nparms = argList->LastIndex() + 1;
5513 Int_t argc = params ? params->GetEntries() : 0;
5514
5515 if (argc > nparms) {
5516 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5517 return;
5518 }
5519 if (nparms != argc) {
5520 // Let's see if the 'missing' argument are all defaulted.
5521 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5522 assert(nparms > 0);
5523
5524 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5525 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5526 // There is a default value for the first missing
5527 // argument, so we are fine.
5528 } else {
5529 Int_t firstDefault = -1;
5530 for (Int_t i = 0; i < nparms; i ++) {
5531 arg = (TMethodArg *) argList->At( i );
5532 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5533 firstDefault = i;
5534 break;
5535 }
5536 }
5537 if (firstDefault >= 0) {
5538 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);
5539 } else {
5540 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5541 }
5542 return;
5543 }
5544 }
5545
5546 const char* listpar = "";
5547 TString complete(10);
5548 if (params) {
5549 // Create a character string of parameters from TObjArray
5550 TIter next(params);
5551 for (Int_t i = 0; i < argc; i ++) {
5552 TMethodArg* arg = (TMethodArg*) argList->At(i);
5554 TObjString* nxtpar = (TObjString*) next();
5555 if (i) {
5556 complete += ',';
5557 }
5558 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5559 TString chpar('\"');
5560 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5561 // At this point we have to check if string contains \\"
5562 // and apply some more sophisticated parser. Not implemented yet!
5563 complete += chpar;
5564 complete += '\"';
5565 }
5566 else {
5567 complete += nxtpar->String();
5568 }
5569 }
5570 listpar = complete.Data();
5571 }
5572
5573 // And now execute it.
5575 if (error) {
5576 *error = TInterpreter::kNoError;
5577 }
5578 // If the actual class of this object inherits 2nd (or more) from TObject,
5579 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5580 // hence gInterpreter->Execute will improperly correct the offset.
5581 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5583 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5584 func.Init(*minfo);
5585 func.SetArgs(listpar);
5586 // Now calculate the 'this' pointer offset for the method
5587 // when starting from the class described by cl.
5588 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5589 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5590 void* address = (void*)((Longptr_t)addr + offset);
5591 func.Exec(address);
5592}
5593
5594////////////////////////////////////////////////////////////////////////////////
5595
5596void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5597 const void* args[] /*=0*/,
5598 int nargs /*=0*/,
5599 void* ret/*= 0*/) const
5600{
5601 if (!method) {
5602 Error("ExecuteWithArgsAndReturn", "No method was defined");
5603 return;
5604 }
5605
5606 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5607 TClingCallFunc func(*minfo);
5608 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5609}
5610
5611////////////////////////////////////////////////////////////////////////////////
5612/// Execute a cling macro.
5613
5615{
5617 fCurExecutingMacros.push_back(filename);
5619 fCurExecutingMacros.pop_back();
5620 return result;
5621}
5622
5623////////////////////////////////////////////////////////////////////////////////
5624/// Return the file name of the current un-included interpreted file.
5625/// See the documentation for GetCurrentMacroName().
5626
5628{
5629 Warning("GetTopLevelMacroName", "Must change return type!");
5630 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5631}
5632
5633////////////////////////////////////////////////////////////////////////////////
5634/// Return the file name of the currently interpreted file,
5635/// included or not. Example to illustrate the difference between
5636/// GetCurrentMacroName() and GetTopLevelMacroName():
5637/// ~~~ {.cpp}
5638/// void inclfile() {
5639/// std::cout << "In inclfile.C" << std::endl;
5640/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5641/// TCling::GetCurrentMacroName() << std::endl;
5642/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5643/// TCling::GetTopLevelMacroName() << std::endl;
5644/// }
5645/// ~~~
5646/// ~~~ {.cpp}
5647/// void mymacro() {
5648/// std::cout << "In mymacro.C" << std::endl;
5649/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5650/// TCling::GetCurrentMacroName() << std::endl;
5651/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5652/// TCling::GetTopLevelMacroName() << std::endl;
5653/// std::cout << " Now calling inclfile..." << std::endl;
5654/// gInterpreter->ProcessLine(".x inclfile.C");
5655/// }
5656/// ~~~
5657/// Running mymacro.C will print:
5658///
5659/// ~~~ {.cpp}
5660/// root [0] .x mymacro.C
5661/// ~~~
5662/// In mymacro.C
5663/// ~~~ {.cpp}
5664/// TCling::GetCurrentMacroName() returns ./mymacro.C
5665/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5666/// ~~~
5667/// Now calling inclfile...
5668/// In inclfile.h
5669/// ~~~ {.cpp}
5670/// TCling::GetCurrentMacroName() returns inclfile.C
5671/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5672/// ~~~
5673
5675{
5676#if defined(R__MUST_REVISIT)
5677#if R__MUST_REVISIT(6,0)
5678 Warning("GetCurrentMacroName", "Must change return type!");
5679#endif
5680#endif
5681 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5682}
5683
5684////////////////////////////////////////////////////////////////////////////////
5685/// Return the absolute type of typeDesc.
5686/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5687/// You need to use the result immediately before it is being overwritten.
5688
5689const char* TCling::TypeName(const char* typeDesc)
5690{
5691 TTHREAD_TLS_DECL(std::string,t);
5692
5693 if (!strstr(typeDesc, "(*)(")) {
5694 const char *s = strchr(typeDesc, ' ');
5695 const char *template_start = strchr(typeDesc, '<');
5696 if (!strcmp(typeDesc, "long long")) {
5697 t = typeDesc;
5698 }
5699 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5700 t = typeDesc;
5701 }
5702 // s is the position of the second 'word' (if any)
5703 // except in the case of templates where there will be a space
5704 // just before any closing '>': eg.
5705 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5706 else if (s && (template_start == nullptr || (s < template_start))) {
5707 t = s + 1;
5708 }
5709 else {
5710 t = typeDesc;
5711 }
5712 }
5713 else {
5714 t = typeDesc;
5715 }
5716 auto l = t.length();
5717 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5718 --l;
5719 t.resize(l);
5720 return t.c_str(); // NOLINT
5721}
5722
5723static bool requiresRootMap(const char* rootmapfile)
5724{
5725 assert(rootmapfile && *rootmapfile);
5726
5727 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5728 libName.consume_back(".rootmap");
5729
5730 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5731}
5732
5733////////////////////////////////////////////////////////////////////////////////
5734/// Read and parse a rootmapfile in its new format, and return 0 in case of
5735/// success, -1 if the file has already been read, and -3 in case its format
5736/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5737/// error.
5738
5739int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5740{
5741 if (!(rootmapfile && *rootmapfile))
5742 return 0;
5743
5744 if (!requiresRootMap(rootmapfile))
5745 return 0; // success
5746
5747 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5748 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5749
5750 std::string rootmapfileNoBackslash(rootmapfile);
5751#ifdef _MSC_VER
5752 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5753#endif
5754 // Add content of a specific rootmap file
5755 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5756 return -1;
5757
5758 // Line 1 is `{ decls }`
5759 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5760
5761 std::ifstream file(rootmapfileNoBackslash);
5762 std::string line;
5763 line.reserve(200);
5764 std::string lib_name;
5765 line.reserve(100);
5766 bool newFormat = false;
5767 while (getline(file, line, '\n')) {
5768 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5769 file.close();
5770 return -3; // old format
5771 }
5772 newFormat = true;
5773
5774 if (line.compare(0, 9, "{ decls }") == 0) {
5775 // forward declarations
5776
5777 while (getline(file, line, '\n')) {
5778 if (line[0] == '[')
5779 break;
5780 if (!uniqueString) {
5781 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5782 rootmapfileNoBackslash.c_str());
5783 return -4;
5784 }
5785 if (!lineDirective.empty())
5786 uniqueString->Append(lineDirective);
5787 uniqueString->Append(line + '\n');
5788 }
5789 }
5790 const char firstChar = line[0];
5791 if (firstChar == '[') {
5792 // new section (library)
5793 auto brpos = line.find(']');
5794 if (brpos == string::npos)
5795 continue;
5796 lib_name = line.substr(1, brpos - 1);
5797 // Remove spaces at the beginning and at the end of the library name
5798 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5799 lib_name.erase(0, lib_name.find_first_not_of(' '));
5800 if (gDebug > 3) {
5801 TString lib_nameTstr(lib_name.c_str());
5802 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5803 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5804 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5805 if (wlib) {
5806 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5807 } else {
5808 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5809 }
5810 delete[] wlib;
5811 delete tokens;
5812 }
5813 } else {
5814 auto keyLenIt = keyLenMap.find(firstChar);
5815 if (keyLenIt == keyLenMap.end())
5816 continue;
5817 unsigned int keyLen = keyLenIt->second;
5818 // Do not make a copy, just start after the key
5819 const char *keyname = line.c_str() + keyLen;
5820 if (gDebug > 6)
5821 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5822 TEnvRec *isThere = fMapfile->Lookup(keyname);
5823 if (isThere) {
5824 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5825 if (firstChar == 'n') {
5826 if (gDebug > 3)
5827 Info("ReadRootmapFile",
5828 "While processing %s, namespace %s was found to be associated to %s although it is already "
5829 "associated to %s",
5830 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5831 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5832 lib_name += " ";
5833 lib_name += isThere->GetValue();
5834 fMapfile->SetValue(keyname, lib_name.c_str());
5835 } else if (!TClassEdit::IsSTLCont(keyname)) {
5836 Warning("ReadRootmapFile",
5837 "While processing %s, %s %s was found to be associated to %s although it is already "
5838 "associated to %s",
5839 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5840 isThere->GetValue());
5841 }
5842 } else { // the same key for the same lib
5843 if (gDebug > 3)
5844 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5845 rootmapfile, keyname, lib_name.c_str());
5846 }
5847 } else {
5848 fMapfile->SetValue(keyname, lib_name.c_str());
5849 }
5850 }
5851 }
5852 file.close();
5853 return 0;
5854}
5855
5856////////////////////////////////////////////////////////////////////////////////
5857/// Create a resource table and read the (possibly) three resource files,
5858/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5859/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5860/// can read additional user defined resource files by creating additional TEnv
5861/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5862/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5863/// case the home directory resides on an automounted remote file system
5864/// and one wants to avoid the file system from being mounted.
5865
5867{
5868 assert(requiresRootMap(name) && "We have a module!");
5869
5870 if (!requiresRootMap(name))
5871 return;
5872
5874
5876
5877 TString sname = "system";
5878 sname += name;
5879 TString temp_sname = sname;
5880 const char *s1 = gSystem->PrependPathName(TROOT::GetEtcDir(), temp_sname);
5881
5882 Int_t ret = ReadRootmapFile(s1);
5883 if (ret == -3) // old format
5885 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5886 TString temp_name = name;
5887 const char *s2 = gSystem->PrependPathName(gSystem->HomeDirectory(), temp_name);
5888 ret = ReadRootmapFile(s2);
5889 if (ret == -3) // old format
5891 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5892 ret = ReadRootmapFile(name);
5893 if (ret == -3) // old format
5895 }
5896 } else {
5897 ret = ReadRootmapFile(name);
5898 if (ret == -3) // old format
5900 }
5901 fMapfile->IgnoreDuplicates(ignore);
5902}
5903
5904
5905namespace {
5906 using namespace clang;
5907
5908 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5909 // This class is to be considered an helper for AutoLoading.
5910 // It is a recursive visitor is used to inspect namespaces and specializations
5911 // coming from forward declarations in rootmaps and to set the external visible
5912 // storage flag for them.
5913 public:
5914 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5915 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5916 // We want to enable the external lookup for this namespace
5917 // because it may shadow the lookup of other names contained
5918 // in that namespace
5919
5920 nsDecl->setHasExternalVisibleStorage();
5921 fNSSet.insert(nsDecl);
5922 return true;
5923 }
5924 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5925 // We want to enable the external lookup for this specialization
5926 // because we can provide a definition for it!
5927 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5928 //SpecSet.insert(specDecl);
5929 specDecl->setHasExternalLexicalStorage();
5930
5931 // No need to recurse. On the contrary, recursing is actively harmful:
5932 // NOTE: must not recurse to prevent this visitor from triggering loading from
5933 // the external AST source (i.e. autoloading). This would be triggered right here,
5934 // before autoloading is even set up, as rootmap file parsing happens before that.
5935 // Even if autoloading is off and has no effect, triggering loading from external
5936 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5937 // from subsequent autoloads!
5938 return false;
5939 }
5940 private:
5941 std::unordered_set<const NamespaceDecl*>& fNSSet;
5942 };
5943}
5944
5945////////////////////////////////////////////////////////////////////////////////
5946/// Load map between class and library. If rootmapfile is specified a
5947/// specific rootmap file can be added (typically used by ACLiC).
5948/// In case of error -1 is returned, 0 otherwise.
5949/// The interpreter uses this information to automatically load the shared
5950/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5951
5952Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5953{
5954 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5955 return 0;
5956
5958
5959 // open the [system].rootmap files
5960 if (!fMapfile) {
5961 fMapfile = new TEnv();
5965 InitRootmapFile(".rootmap");
5966 }
5967
5968 // Prepare a list of all forward declarations for cling
5969 // For some experiments it is easily as big as 500k characters. To be on the
5970 // safe side, we go for 1M.
5971 TUniqueString uniqueString(1048576);
5972
5973 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5974 // A rootmap file must end with the string ".rootmap".
5975 TString ldpath = gSystem->GetDynamicPath();
5976 if (ldpath != fRootmapLoadPath) {
5977 fRootmapLoadPath = ldpath;
5978#ifdef WIN32
5979 TObjArray* paths = ldpath.Tokenize(";");
5980#else
5981 TObjArray* paths = ldpath.Tokenize(":");
5982#endif
5983 TString d;
5984 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5985 d = ((TObjString *)paths->At(i))->GetString();
5986 // check if directory already scanned
5987 Int_t skip = 0;
5988 for (Int_t j = 0; j < i; j++) {
5989 TString pd = ((TObjString *)paths->At(j))->GetString();
5990 if (pd == d) {
5991 skip++;
5992 break;
5993 }
5994 }
5995 if (!skip) {
5996 void* dirp = gSystem->OpenDirectory(d);
5997 if (dirp) {
5998 if (gDebug > 3) {
5999 Info("LoadLibraryMap", "%s", d.Data());
6000 }
6001 const char* f1;
6002 while ((f1 = gSystem->GetDirEntry(dirp))) {
6003 TString f = f1;
6004 if (f.EndsWith(".rootmap")) {
6005 TString p;
6006 p = d + "/" + f;
6008 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
6009 if (gDebug > 4) {
6010 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
6011 }
6012 Int_t ret = ReadRootmapFile(p, &uniqueString);
6013
6014 if (ret == 0)
6015 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
6016 if (ret == -3) {
6017 // old format
6019 fRootmapFiles->Add(new TNamed(f, p));
6020 }
6021 }
6022 // else {
6023 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
6024 // fRootmapFiles->FindObject(f)->ls();
6025 // }
6026 }
6027 }
6028 if (f.BeginsWith("rootmap")) {
6029 TString p;
6030 p = d + "/" + f;
6031 FileStat_t stat;
6032 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
6033 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
6034 }
6035 }
6036 }
6037 }
6038 gSystem->FreeDirectory(dirp);
6039 }
6040 }
6041 delete paths;
6042 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
6043 return -1;
6044 }
6045 }
6046 if (rootmapfile && *rootmapfile) {
6047 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
6048 if (res == 0) {
6049 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
6050 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
6051 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
6052 }
6053 else if (res == -3) {
6054 // old format
6056 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
6057 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
6058 fMapfile->IgnoreDuplicates(ignore);
6059 }
6060 }
6061 TEnvRec* rec;
6062 TIter next(fMapfile->GetTable());
6063 while ((rec = (TEnvRec*) next())) {
6064 TString cls = rec->GetName();
6065 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6066 // get the first lib from the list of lib and dependent libs
6067 TString libs = rec->GetValue();
6068 if (libs == "") {
6069 continue;
6070 }
6071 TString delim(" ");
6072 TObjArray* tokens = libs.Tokenize(delim);
6073 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6074 // convert "@@" to "::", we used "@@" because TEnv
6075 // considers "::" a terminator
6076 cls.Remove(0, 8);
6077 cls.ReplaceAll("@@", "::");
6078 // convert "-" to " ", since class names may have
6079 // blanks and TEnv considers a blank a terminator
6080 cls.ReplaceAll("-", " ");
6081 if (gDebug > 6) {
6082 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
6083 if (wlib) {
6084 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
6085 }
6086 else {
6087 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
6088 }
6089 delete[] wlib;
6090 }
6091 delete tokens;
6092 }
6093 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
6094 cls.Remove(0, 8);
6095 // convert "-" to " ", since class names may have
6096 // blanks and TEnv considers a blank a terminator
6097 cls.ReplaceAll("-", " ");
6098 fInterpreter->declare(cls.Data());
6099 }
6100 }
6101
6102 // Process the forward declarations collected
6103 cling::Transaction* T = nullptr;
6104 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
6105 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
6106
6107 if (compRes!=cling::Interpreter::kSuccess){
6108 Warning("LoadLibraryMap",
6109 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
6110 }
6111
6112 if (T) {
6113 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
6114 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
6115 if (declIt->m_DGR.isSingleDecl()) {
6116 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
6117 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
6118 evsAdder.TraverseDecl(D);
6119 }
6120 }
6121 }
6122 }
6123 }
6124
6125 // clear duplicates
6126
6127 return 0;
6128}
6129
6130////////////////////////////////////////////////////////////////////////////////
6131/// Scan again along the dynamic path for library maps. Entries for the loaded
6132/// shared libraries are unloaded first. This can be useful after reseting
6133/// the dynamic path through TSystem::SetDynamicPath()
6134/// In case of error -1 is returned, 0 otherwise.
6135
6142
6143////////////////////////////////////////////////////////////////////////////////
6144/// Reload the library map entries coming from all the loaded shared libraries,
6145/// after first unloading the current ones.
6146/// In case of error -1 is returned, 0 otherwise.
6147
6149{
6150 const TString sharedLibLStr = GetSharedLibs();
6151 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6152 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
6153 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
6154 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6155 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6156 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
6157 if (ret < 0) {
6158 continue;
6159 }
6160 TString rootMapBaseStr = sharedLibBaseStr;
6161 if (sharedLibBaseStr.EndsWith(".dll")) {
6162 rootMapBaseStr.ReplaceAll(".dll", "");
6163 }
6164 else if (sharedLibBaseStr.EndsWith(".DLL")) {
6165 rootMapBaseStr.ReplaceAll(".DLL", "");
6166 }
6167 else if (sharedLibBaseStr.EndsWith(".so")) {
6168 rootMapBaseStr.ReplaceAll(".so", "");
6169 }
6170 else if (sharedLibBaseStr.EndsWith(".sl")) {
6171 rootMapBaseStr.ReplaceAll(".sl", "");
6172 }
6173 else if (sharedLibBaseStr.EndsWith(".dl")) {
6174 rootMapBaseStr.ReplaceAll(".dl", "");
6175 }
6176 else if (sharedLibBaseStr.EndsWith(".a")) {
6177 rootMapBaseStr.ReplaceAll(".a", "");
6178 }
6179 else {
6180 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6181 delete sharedLibL;
6182 return -1;
6183 }
6184 rootMapBaseStr += ".rootmap";
6185 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
6186 if (!rootMap) {
6187 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6188 delete[] rootMap;
6189 delete sharedLibL;
6190 return -1;
6191 }
6192 const Int_t status = LoadLibraryMap(rootMap);
6193 if (status < 0) {
6194 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6195 delete[] rootMap;
6196 delete sharedLibL;
6197 return -1;
6198 }
6199 delete[] rootMap;
6200 }
6201 delete sharedLibL;
6202 return 0;
6203}
6204
6205////////////////////////////////////////////////////////////////////////////////
6206/// Unload the library map entries coming from all the loaded shared libraries.
6207/// Returns 0 if succesful
6208
6210{
6211 const TString sharedLibLStr = GetSharedLibs();
6212 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6213 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6214 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6215 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6216 UnloadLibraryMap(sharedLibBaseStr);
6217 }
6218 delete sharedLibL;
6219 return 0;
6220}
6221
6222////////////////////////////////////////////////////////////////////////////////
6223/// Unload library map entries coming from the specified library.
6224/// Returns -1 in case no entries for the specified library were found,
6225/// 0 otherwise.
6226
6228{
6229 if (!fMapfile || !library || !*library) {
6230 return 0;
6231 }
6232 TString libname(library);
6233 Ssiz_t idx = libname.Last('.');
6234 if (idx != kNPOS) {
6235 libname.Remove(idx);
6236 }
6237 size_t len = libname.Length();
6238 TEnvRec *rec;
6239 TIter next(fMapfile->GetTable());
6241 Int_t ret = 0;
6242 while ((rec = (TEnvRec *) next())) {
6243 TString cls = rec->GetName();
6244 if (cls.Length() > 2) {
6245 // get the first lib from the list of lib and dependent libs
6246 TString libs = rec->GetValue();
6247 if (libs == "") {
6248 continue;
6249 }
6250 TString delim(" ");
6251 TObjArray* tokens = libs.Tokenize(delim);
6252 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6253 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6254 // convert "@@" to "::", we used "@@" because TEnv
6255 // considers "::" a terminator
6256 cls.Remove(0, 8);
6257 cls.ReplaceAll("@@", "::");
6258 // convert "-" to " ", since class names may have
6259 // blanks and TEnv considers a blank a terminator
6260 cls.ReplaceAll("-", " ");
6261 }
6262 if (!strncmp(lib, libname.Data(), len)) {
6263 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6264 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6265 ret = -1;
6266 }
6267 }
6268 delete tokens;
6269 }
6270 }
6271 if (ret >= 0) {
6272 TString library_rootmap(library);
6273 if (!library_rootmap.EndsWith(".rootmap"))
6274 library_rootmap.Append(".rootmap");
6275 TNamed* mfile = nullptr;
6276 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6277 fRootmapFiles->Remove(mfile);
6278 delete mfile;
6279 }
6281 }
6282 return ret;
6283}
6284
6285////////////////////////////////////////////////////////////////////////////////
6286/// Register the AutoLoading information for a class.
6287/// libs is a space separated list of libraries.
6288
6289Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6290{
6291 if (!cls || !*cls)
6292 return 0;
6293
6294 TString key = TString("Library.") + cls;
6295 // convert "::" to "@@", we used "@@" because TEnv
6296 // considers "::" a terminator
6297 key.ReplaceAll("::", "@@");
6298 // convert "-" to " ", since class names may have
6299 // blanks and TEnv considers a blank a terminator
6300 key.ReplaceAll(" ", "-");
6301
6303 if (!fMapfile) {
6304 fMapfile = new TEnv();
6306
6309
6310 InitRootmapFile(".rootmap");
6311 }
6312 //fMapfile->SetValue(key, libs);
6313 fMapfile->SetValue(cls, libs);
6314 return 1;
6315}
6316
6317////////////////////////////////////////////////////////////////////////////////
6318/// Demangle the name (from the typeinfo) and then request the class
6319/// via the usual name based interface (TClass::GetClass).
6320
6321TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6322{
6323 int err = 0;
6324 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6325 if (err) return nullptr;
6326 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6327 free(demangled_name);
6328 return theClass;
6329}
6330
6331////////////////////////////////////////////////////////////////////////////////
6332/// Load library containing the specified class. Returns 0 in case of error
6333/// and 1 in case if success.
6334
6335Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6336{
6337 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6338
6339 int err = 0;
6340 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6341 if (err) {
6342 return 0;
6343 }
6344
6345 std::string demangled_name(demangled_name_c);
6346 free(demangled_name_c);
6347
6348 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6349 // shortened name.
6351 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6352
6353 // No need to worry about typedef, they aren't any ... but there are
6354 // inlined namespaces ...
6355
6356 Int_t result = AutoLoad(demangled_name.c_str());
6357 if (result == 0) {
6358 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6359 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6360 }
6361
6362 return result;
6363}
6364
6365////////////////////////////////////////////////////////////////////////////////
6366// Get the list of 'published'/'known' library for the class and load them.
6368{
6369 Int_t status = 0;
6370
6371 // lookup class to find list of dependent libraries
6372 TString deplibs = gCling->GetClassSharedLibs(cls);
6373 if (!deplibs.IsNull()) {
6374 TString delim(" ");
6375 TObjArray* tokens = deplibs.Tokenize(delim);
6376 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6377 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6378 if (gROOT->LoadClass(cls, deplib) == 0) {
6379 if (gDebug > 0) {
6380 gCling->Info("TCling::AutoLoad",
6381 "loaded dependent library %s for %s", deplib, cls);
6382 }
6383 }
6384 else {
6385 gCling->Error("TCling::AutoLoad",
6386 "failure loading dependent library %s for %s",
6387 deplib, cls);
6388 }
6389 }
6390 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6391 if (lib && lib[0]) {
6392 if (gROOT->LoadClass(cls, lib) == 0) {
6393 if (gDebug > 0) {
6394 gCling->Info("TCling::AutoLoad",
6395 "loaded library %s for %s", lib, cls);
6396 }
6397 status = 1;
6398 }
6399 else {
6400 gCling->Error("TCling::AutoLoad",
6401 "failure loading library %s for %s", lib, cls);
6402 }
6403 }
6404 delete tokens;
6405 }
6406
6407 return status;
6408}
6409
6410////////////////////////////////////////////////////////////////////////////////
6411// Iterate through the data member of the class (either through the TProtoClass
6412// or through Cling) and trigger, recursively, the loading the necessary libraries.
6413// \note `cls` is expected to be already normalized!
6414// \returns 1 on success.
6415Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6416 bool nameIsNormalized)
6417{
6418 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6419 // has previously (within the same call to `AutoLoad()`) tried to load this class
6420 // and we are done, whether success or not, as it won't work better now than before,
6421 // because there is no additional information now compared to before.
6422 if (!visited.insert(std::string(cls)).second)
6423 return 1;
6424
6425 if (ShallowAutoLoadImpl(cls) == 0) {
6426 // If ShallowAutoLoadImpl() has an error, we have an error.
6427 return 0;
6428 }
6429
6430 // Now look through the TProtoClass to load the required library/dictionary
6431 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6432 for (auto element : proto->GetData()) {
6433 if (element->IsBasic())
6434 continue;
6435 const char *subtypename = element->GetTypeName();
6436 if (!TClassTable::GetDictNorm(subtypename)) {
6437 // Failure to load a dictionary is not (quite) a failure load
6438 // the top-level library. If we return false here, then
6439 // we would end up in a situation where the library and thus
6440 // the dictionary is loaded for "cls" but the TClass is
6441 // not created and/or marked as unavailable (in case where
6442 // AutoLoad is called from TClass::GetClass).
6443 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6444 }
6445 }
6446 return 1;
6447 }
6448
6449 // We found no TProtoClass for cls.
6450 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6451 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6452 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6453 {
6454 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6455 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6456 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6457 continue;
6458 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6459 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6460 // Failure to load a dictionary is not (quite) a failure load
6461 // the top-level library. See detailed comment in the TProtoClass
6462 // branch (above).
6463 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6464 }
6465 }
6466 gInterpreter->DataMemberInfo_Delete(memberinfo);
6467 }
6468 gInterpreter->ClassInfo_Delete(classinfo);
6469 return 1;
6470}
6471
6472////////////////////////////////////////////////////////////////////////////////
6473/// Load library containing the specified class. Returns 0 in case of error
6474/// and 1 in case if success.
6475
6476Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6477{
6478 // Prevent update to IsClassAutoloading between our check and our actions.
6480
6481 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6482 // rootcling (in *_rdict.pcm file generation) it is a no op.
6483 // FIXME: We should avoid calling autoload when we know we are not supposed
6484 // to and transform this check into an assert.
6486 // Never load any library from rootcling/genreflex.
6487 if (gDebug > 2) {
6488 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6489 }
6490 return 0;
6491 }
6492
6493 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6494
6496
6497 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6498 // The library is already loaded as the class's dictionary is known.
6499 // Return success.
6500 // Note: the name (cls) is expected to be normalized as it comes either
6501 // from a callbacks (that can/should calculate the normalized name from the
6502 // decl) or from TClass::GetClass (which does also calculate the normalized
6503 // name).
6504 return 1;
6505 }
6506
6507 if (gDebug > 2) {
6508 Info("TCling::AutoLoad",
6509 "Trying to autoload for %s", cls);
6510 }
6511
6512 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6513 if (gDebug > 2) {
6514 Info("TCling::AutoLoad",
6515 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6516 }
6517 return 0;
6518 }
6519 // Prevent the recursion when the library dictionary are loaded.
6520 SuspendAutoLoadingRAII autoLoadOff(this);
6521 // Try using externally provided callback first.
6522 if (fAutoLoadCallBack) {
6523 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6524 if (success)
6525 return success;
6526 }
6527
6528 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6529 // (when module are enabled) which might end up calling AutoParsing but
6530 // that should only be for the cases where the library has no generated pcm
6531 // and in that case a rootmap should be available.
6532 // This avoids a very costly operation (for generally no gain) but reduce the
6533 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6534 // file).
6535 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6536 std::unordered_set<std::string> visited;
6537 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6538}
6539
6540////////////////////////////////////////////////////////////////////////////////
6541/// Parse the payload or header.
6542
6543static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6544 Bool_t header,
6545 cling::Interpreter *interpreter)
6546{
6547 std::string code = gNonInterpreterClassDef ;
6548 if (!header) {
6549 // This is the complete header file content and not the
6550 // name of a header.
6551 code += what;
6552
6553 } else {
6554 code += ("#include \"");
6555 code += what;
6556 code += "\"\n";
6557 }
6558 code += ("#ifdef __ROOTCLING__\n"
6559 "#undef __ROOTCLING__\n"
6560 + gInterpreterClassDef +
6561 "#endif");
6562
6563 cling::Interpreter::CompilationResult cr;
6564 {
6565 // scope within which diagnostics are de-activated
6566 // For now we disable diagnostics because we saw them already at
6567 // dictionary generation time. That won't be an issue with the PCMs.
6568
6569 Sema &SemaR = interpreter->getSema();
6570 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6571 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6572
6573 #if defined(R__MUST_REVISIT)
6574 #if R__MUST_REVISIT(6,2)
6575 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6576 #endif
6577 #endif
6578
6579 cr = interpreter->parseForModule(code);
6580 }
6581 return cr;
6582}
6583
6584////////////////////////////////////////////////////////////////////////////////
6585/// Helper routine for TCling::AutoParse implementing the actual call to the
6586/// parser and looping over template parameters (if
6587/// any) and when they don't have a registered header to autoparse,
6588/// recurse over their template parameters.
6589///
6590/// Returns the number of header parsed.
6591
6592UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6593{
6594 // We assume the lock has already been taken.
6595 // R__LOCKGUARD(gInterpreterMutex);
6596
6597 Int_t nHheadersParsed = 0;
6598 unsigned long offset = 0;
6599 if (strncmp(cls, "const ", 6) == 0) {
6600 offset = 6;
6601 }
6602
6603 // Loop on the possible autoparse keys
6604 bool skipFirstEntry = false;
6605 std::vector<std::string> autoparseKeys;
6606 if (strchr(cls, '<')) {
6607 int nestedLoc = 0;
6608 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6609 // Check if we can skip the name of the template in the autoparses
6610 // Take all the scopes one by one. If all of them are in the AST, we do not
6611 // need to autoparse for that particular template.
6612 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6613 // autoparseKeys[0] is empty when the input is not a template instance.
6614 // The case strchr(cls, '<') != 0 but still not a template instance can
6615 // happens 'just' for string (GetSplit replaces the template by the short name
6616 // and then use that for thew splitting)
6617 TString templateName(autoparseKeys[0]);
6618 auto tokens = templateName.Tokenize("::");
6619 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6620 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6621 if (TClassEdit::IsStdClass(cls + offset))
6622 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6623 auto nTokens = tokens->GetEntriesFast();
6624 for (Int_t tk = 0; tk < nTokens; ++tk) {
6625 auto scopeObj = tokens->UncheckedAt(tk);
6626 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6627 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6628 // Check if we have multiple nodes in the AST with this name
6629 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6630 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6631 if (!previousScopeAsContext) break; // this is not a context
6632 }
6633 delete tokens;
6634 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6635 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6636 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6637 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6638 skipFirstEntry = templatedDecl->hasDefinition();
6639 }
6640 }
6641 }
6642
6643 }
6644 }
6645 if (topLevel) autoparseKeys.emplace_back(cls);
6646
6647 for (const auto & apKeyStr : autoparseKeys) {
6648 if (skipFirstEntry) {
6649 skipFirstEntry=false;
6650 continue;
6651 }
6652 if (apKeyStr.empty()) continue;
6653 const char *apKey = apKeyStr.c_str();
6654 std::size_t normNameHash(fStringHashFunction(apKey));
6655 // If the class was not looked up
6656 if (gDebug > 1) {
6657 Info("TCling::AutoParse",
6658 "Starting autoparse for %s\n", apKey);
6659 }
6660 if (fLookedUpClasses.insert(normNameHash).second) {
6661 auto const &iter = fClassesHeadersMap.find(normNameHash);
6662 if (iter != fClassesHeadersMap.end()) {
6663 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6664 fTransactionHeadersMap.insert({T,normNameHash});
6665 auto const &hNamesPtrs = iter->second;
6666 if (gDebug > 1) {
6667 Info("TCling::AutoParse",
6668 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6669 }
6670 for (auto & hName : hNamesPtrs) {
6671 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6672 if (0 != fPayloads.count(normNameHash)) {
6673 float initRSSval=0.f, initVSIZEval=0.f;
6674 (void) initRSSval; // Avoid unused var warning
6675 (void) initVSIZEval;
6676 if (gDebug > 0) {
6677 Info("AutoParse",
6678 "Parsing full payload for %s", apKey);
6679 ProcInfo_t info;
6680 gSystem->GetProcInfo(&info);
6681 initRSSval = 1e-3*info.fMemResident;
6682 initVSIZEval = 1e-3*info.fMemVirtual;
6683 }
6684 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6685 if (cRes != cling::Interpreter::kSuccess) {
6686 if (hName[0] == '\n')
6687 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6688 } else {
6689 fParsedPayloadsAddresses.insert(hName);
6690 nHheadersParsed++;
6691 if (gDebug > 0){
6692 ProcInfo_t info;
6693 gSystem->GetProcInfo(&info);
6694 float endRSSval = 1e-3*info.fMemResident;
6695 float endVSIZEval = 1e-3*info.fMemVirtual;
6696 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6697 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6698 }
6699 }
6700 } else if (!IsLoaded(hName)) {
6701 if (gDebug > 0) {
6702 Info("AutoParse",
6703 "Parsing single header %s", hName);
6704 }
6705 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6706 if (cRes != cling::Interpreter::kSuccess) {
6707 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6708 } else {
6709 nHheadersParsed++;
6710 }
6711 }
6712 }
6713 }
6714 else {
6715 // There is no header registered for this class, if this a
6716 // template, it will be instantiated if/when it is requested
6717 // and if we do no load/parse its components we might end up
6718 // not using an eventual specialization.
6719 if (strchr(apKey, '<')) {
6720 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6721 }
6722 }
6723 }
6724 }
6725
6726 if (nHheadersParsed) {
6727 // Register that we did autoparsing for this class.
6728 fAutoParseClasses.insert(cls);
6729 if (gDebug)
6730 Info("AutoParse", "Parsed %d headers for %s", nHheadersParsed, cls);
6731 }
6732 return nHheadersParsed;
6733
6734}
6735
6736////////////////////////////////////////////////////////////////////////////////
6737/// Parse the headers relative to the class
6738/// Returns 1 in case of success, 0 in case of failure
6739
6740Int_t TCling::AutoParse(const char *cls)
6741{
6742 if (llvm::StringRef(cls).contains("(lambda)"))
6743 return 0;
6744
6747 return AutoLoad(cls);
6748 } else {
6749 return 0;
6750 }
6751 }
6752
6754
6755 if (gDebug > 1) {
6756 Info("TCling::AutoParse",
6757 "Trying to autoparse for %s", cls);
6758 }
6759
6760 // The catalogue of headers is in the dictionary
6762 && !gClassTable->GetDictNorm(cls)) {
6763 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6764 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6765 fInterpreter->getSema());
6766 AutoLoad(cls, true /*knowDictNotLoaded*/);
6767 }
6768
6769 // Prevent the recursion when the library dictionary are loaded.
6770 SuspendAutoLoadingRAII autoLoadOff(this);
6771
6772 // No recursive header parsing on demand; we require headers to be standalone.
6773 SuspendAutoParsing autoParseRAII(this);
6774
6775 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6776
6778
6779 return nHheadersParsed > 0 ? 1 : 0;
6780}
6781
6782// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6783// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6784// false if not.
6785bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6786{
6787 StringRef errMsg(errmessage);
6788 if (errMsg.contains("undefined symbol: ")) {
6789 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6790 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6791 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6792 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6793 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6794 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6795 return true;
6796 } else {
6797 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6798 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6799 return true;
6800 }
6801
6802 return false;
6803}
6804
6805////////////////////////////////////////////////////////////////////////////////
6806/// Autoload a library based on a missing symbol.
6807
6808void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6809 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6810
6811 // We have already loaded the library.
6812 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6813 return Addr;
6814
6815 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6817
6818 auto LibLoader = [](const std::string& LibName) -> bool {
6819 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6820 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6821 "Failed to load library %s", LibName.c_str());
6822 return false;
6823 }
6824 return true; //success.
6825 };
6826
6827 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6828 /*searchSystem=*/ true);
6829
6830 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6831
6832 if (libName.empty())
6833 return nullptr;
6834
6835 if (!LibLoader(libName))
6836 return nullptr;
6837
6838 fAutoLoadedLibraries.insert(libName);
6839 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6840}
6841
6842////////////////////////////////////////////////////////////////////////////////
6843
6844Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6845{
6846 return fNSFromRootmaps.count(nsDecl) != 0;
6847}
6848
6849////////////////////////////////////////////////////////////////////////////////
6850/// Internal function. Actually do the update of the ClassInfo when seeing
6851// new TagDecl or NamespaceDecl.
6852void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6853{
6854
6856 if (cci) {
6857 // If we only had a forward declaration then update the
6858 // TClingClassInfo with the definition if we have it now.
6859 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6860 if (!oldDef || (def && def != oldDef)) {
6861 cl->ResetCaches();
6862 TClass::RemoveClassDeclId(cci->GetDeclId());
6863 if (def) {
6864 if (cci->GetType()) {
6865 // It's a tag decl, not a namespace decl.
6866 cci->Init(*cci->GetType());
6867 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6868 } else {
6869 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6870 }
6871 }
6872 }
6873 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6874 cl->ResetCaches();
6875 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6876 // We need to use the Emulated Tuple but we should not trigger parsing
6877 // yet, so delay the creation of the ClassInfo
6878 delete ((TClingClassInfo *)cl->fClassInfo);
6879 cl->fClassInfo = nullptr;
6880 cl->fCanLoadClassInfo = true;
6882 if (cl->fState != TClass::kHasTClassInit) {
6884 }
6885 return;
6886 }
6887 // yes, this is almost a waste of time, but we do need to lookup
6888 // the 'type' corresponding to the TClass anyway in order to
6889 // preserve the opaque typedefs (Double32_t)
6890 if (!alias && def != nullptr)
6891 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6892 else
6893 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6894 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6895 // We now need to update the state and bits.
6896 if (cl->fState != TClass::kHasTClassInit) {
6897 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6899 }
6900 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6901 } else {
6902 delete ((TClingClassInfo *)cl->fClassInfo);
6903 cl->fClassInfo = nullptr;
6904 }
6905 }
6906}
6907
6908////////////////////////////////////////////////////////////////////////////////
6909/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6910void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6911{
6912 const TagDecl *td = dyn_cast<TagDecl>(ND);
6913 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6914 const NamedDecl *canon = nullptr;
6915
6916 std::string name;
6917 TagDecl* tdDef = nullptr;
6918 if (td) {
6919 canon = tdDef = td->getDefinition();
6920 // Let's pass the decl to the TClass only if it has a definition.
6921 if (!tdDef) return;
6922
6923 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6924 // Ignore incomplete definition.
6925 // Ignore declaration within a function.
6926 return;
6927 }
6928
6929 auto declName = tdDef->getNameAsString();
6930 // Check if we have registered the unqualified name into the list
6931 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6932 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6933 // the unqualified name is sufficient (and the fully qualified name might be
6934 // 'wrong' if there is difference in spelling in the template paramters (for example)
6935 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6936 // 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() );
6937 return;
6938 }
6939
6940 clang::QualType type = tdDef->getASTContext().getCanonicalTagType(tdDef);
6942 } else if (ns) {
6943 canon = ns->getCanonicalDecl();
6944 name = ND->getQualifiedNameAsString();
6945 } else {
6946 name = ND->getQualifiedNameAsString();
6947 }
6948
6949 // Supposedly we are being called while something is being
6950 // loaded ... let's now tell the autoloader to do the work
6951 // yet another time.
6952 SuspendAutoLoadingRAII autoLoadOff(this);
6953 // FIXME: There can be more than one TClass for a single decl.
6954 // for example vector<double> and vector<Double32_t>
6955 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6956 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6957 RefreshClassInfo(cl, canon, false);
6958 }
6959 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6960 // and update them too:
6961 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6962 // RefreshClassInfo(cl, tdDef, true);
6963}
6964
6965////////////////////////////////////////////////////////////////////////////////
6966/// No op: see TClingCallbacks
6967
6968void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6969{
6970}
6971
6972//______________________________________________________________________________
6973//FIXME: Factor out that function in TClass, because TClass does it already twice
6974void TCling::UpdateClassInfoWork(const char* item)
6975{
6976 // This is a no-op as part of the API.
6977 // TCling uses UpdateClassInfoWithDecl() instead.
6978}
6979
6980////////////////////////////////////////////////////////////////////////////////
6981/// Update all canvases at end the terminal input command.
6982
6984{
6985 TIter next(gROOT->GetListOfCanvases());
6986 TVirtualPad* canvas;
6987 while ((canvas = (TVirtualPad*)next())) {
6988 canvas->Update();
6989 }
6990}
6991
6992////////////////////////////////////////////////////////////////////////////////
6993
6994void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6995 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6996
6997 // If the transaction does not contain anything we can return earlier.
6998 if (!HandleNewTransaction(T)) return;
6999
7000 bool isTUTransaction = false;
7001 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
7002 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
7003 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
7004 // The is the first transaction, we have to expose to meta
7005 // what's already in the AST.
7006 isTUTransaction = true;
7007 }
7008 }
7009
7010 std::set<const void*> TransactionDeclSet;
7011 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
7012 const clang::Decl* WrapperFD = T.getWrapperFD();
7013 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7014 I != E; ++I) {
7015 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
7016 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
7017 continue;
7018
7019 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7020 DE = I->m_DGR.end(); DI != DE; ++DI) {
7021 if (*DI == WrapperFD)
7022 continue;
7023 TransactionDeclSet.insert(*DI);
7024 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
7025 }
7026 }
7027 }
7028
7029 // The above might trigger more decls to be deserialized.
7030 // Thus the iteration over the deserialized decls must be last.
7031 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
7032 E = T.deserialized_decls_end(); I != E; ++I) {
7033 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7034 DE = I->m_DGR.end(); DI != DE; ++DI)
7035 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
7036 //FIXME: HandleNewDecl should take DeclGroupRef
7037 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
7038 modifiedTClasses);
7039 }
7040 }
7041
7042
7043 // When fully building the reflection info in TClass, a deserialization
7044 // could be triggered, which may result in request for building the
7045 // reflection info for the same TClass. This in turn will clear the caches
7046 // for the TClass in-flight and cause null ptr derefs.
7047 // FIXME: This is a quick fix, solving most of the issues. The actual
7048 // question is: Shouldn't TClass provide a lock mechanism on update or lock
7049 // itself until the update is done.
7050 //
7051 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
7052 std::vector<TClass*>::iterator it;
7053 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
7054 ((TCling*)gCling)->GetModTClasses().begin(),
7055 ((TCling*)gCling)->GetModTClasses().end(),
7056 modifiedTClassesDiff.begin());
7057 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
7058
7059 // Lock the TClass for updates
7060 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
7061 modifiedTClassesDiff.end());
7062 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
7063 E = modifiedTClassesDiff.end(); I != E; ++I) {
7064 // Make sure the TClass has not been deleted.
7065 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
7066 continue;
7067 }
7068 // Could trigger deserialization of decls.
7069 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
7070 // Unlock the TClass for updates
7071 ((TCling*)gCling)->GetModTClasses().erase(*I);
7072
7073 }
7074}
7075
7076///\brief Invalidate stored TCling state for declarations included in transaction `T'.
7077///
7078void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
7079{
7081
7082 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7083 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7084 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7085 (TListOfEnums *)gROOT->GetListOfEnums());
7086
7087 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
7088 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7089 I != E; ++I) {
7090 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
7091 continue;
7092 if (I->m_Call == cling::Transaction::kCCINone) {
7093 UpdateListsOnUnloaded(*(*iNested));
7094 ++iNested;
7095 continue;
7096 }
7097
7098 for (auto &D : I->m_DGR)
7099 InvalidateCachedDecl(Lists, D);
7100 }
7101}
7102
7103///\brief Invalidate cached TCling information for the given global declaration.
7104///
7105void TCling::InvalidateGlobal(const Decl *D) {
7106 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7107 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7108 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7109 (TListOfEnums *)gROOT->GetListOfEnums());
7110 InvalidateCachedDecl(Lists, D);
7111}
7112
7113///\brief Invalidate cached TCling information for the given declaration, and
7114/// removed it from the appropriate object list.
7115///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
7116/// TListOfFunctionTemplates&, TListOfEnums&>
7117/// of pointers to the (global/class) object lists.
7118///\param[in] D - Decl to discard.
7119///
7123 TListOfEnums*> &Lists, const Decl *D) {
7124 if (D->isFromASTFile()) // `D' came from the PCH; ignore
7125 return;
7126
7127 TListOfDataMembers &LODM = *(std::get<0>(Lists));
7128 TListOfFunctions &LOF = *(std::get<1>(Lists));
7129 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
7130 TListOfEnums &LOE = *(std::get<3>(Lists));
7131
7132 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
7133 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
7134 if (LODM.GetClass())
7135 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
7136 else
7137 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
7138 } else if (isa<FunctionDecl>(D)) {
7140 } else if (isa<FunctionTemplateDecl>(D)) {
7142 } else if (isa<EnumDecl>(D)) {
7143 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
7144 if (!E)
7145 return;
7146
7147 // Try to invalidate enumerators (for unscoped enumerations).
7148 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
7150 (TEnumConstant *)LODM.FindObject(EC->GetName()));
7151
7153 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
7154 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
7155 return;
7156
7157 std::vector<TClass *> Classes;
7158 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
7159 return;
7160 for (auto &C : Classes) {
7161 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
7162 (TListOfFunctions *)C->GetListOfMethods(),
7163 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
7164 (TListOfEnums *)C->GetListOfEnums());
7165 for (auto &I : cast<DeclContext>(D)->decls())
7166 InvalidateCachedDecl(Lists, I);
7167
7168 // For NamespaceDecl (redeclarable), only invalidate this redecl.
7169 if (D->getKind() != Decl::Namespace || cast<NamespaceDecl>(D)->isFirstDecl())
7170 C->ResetClassInfo();
7171 }
7172 }
7173}
7174
7175////////////////////////////////////////////////////////////////////////////////
7176// If an autoparse was done during a transaction and that it is rolled back,
7177// we need to make sure the next request for the same autoparse will be
7178// honored.
7179void TCling::TransactionRollback(const cling::Transaction &T) {
7180 auto const &triter = fTransactionHeadersMap.find(&T);
7181 if (triter != fTransactionHeadersMap.end()) {
7182 std::size_t normNameHash = triter->second;
7183
7184 fLookedUpClasses.erase(normNameHash);
7185
7186 auto const &iter = fClassesHeadersMap.find(normNameHash);
7187 if (iter != fClassesHeadersMap.end()) {
7188 auto const &hNamesPtrs = iter->second;
7189 for (auto &hName : hNamesPtrs) {
7190 if (gDebug > 0) {
7191 Info("TransactionRollback",
7192 "Restoring ability to autoaparse: %s", hName);
7193 }
7194 fParsedPayloadsAddresses.erase(hName);
7195 }
7196 }
7197 }
7198}
7199
7200////////////////////////////////////////////////////////////////////////////////
7201
7202void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7203// R__LOCKGUARD_CLING(gInterpreterMutex);
7204// UpdateListOfLoadedSharedLibraries();
7205}
7206
7207////////////////////////////////////////////////////////////////////////////////
7208
7209void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7210 fPrevLoadedDynLibInfo = nullptr;
7211 fSharedLibs = "";
7212}
7213
7214////////////////////////////////////////////////////////////////////////////////
7215/// Return the list of shared libraries loaded into the process.
7216
7223
7224static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7225{
7226 if (!cls || !*cls)
7227 return {};
7228
7229 using namespace clang;
7230 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7231 /*type*/ nullptr, /*instantiate*/ false)) {
7232 if (!D->isFromASTFile()) {
7233 if (gDebug > 5)
7234 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7235 return {};
7236 }
7237 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7238 llvm::DenseSet<Module *> &m_TopLevelModules;
7239
7240 public:
7241 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7242 void Collect(const Decl *D) { Visit(D); }
7243
7244 void VisitDecl(const Decl *D)
7245 {
7246 // FIXME: Such case is described ROOT-7765 where
7247 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7248 // They are specified as #includes in the LinkDef file. This leads to
7249 // generation of incomplete modulemap files and this logic fails to
7250 // compute the corresponding module of D.
7251 // FIXME: If we want to support such a case, we should not rely on
7252 // the contents of the modulemap but mangle D and look it up in the
7253 // .so files.
7254 if (!D->hasOwningModule())
7255 return;
7256 if (Module *M = D->getOwningModule()->getTopLevelModule())
7257 m_TopLevelModules.insert(M);
7258 }
7259
7260 void VisitTemplateArgument(const TemplateArgument &TA)
7261 {
7262 switch (TA.getKind()) {
7263 case TemplateArgument::Null:
7264 case TemplateArgument::Integral:
7265 case TemplateArgument::Pack:
7266 case TemplateArgument::NullPtr:
7267 case TemplateArgument::StructuralValue:
7268 case TemplateArgument::Expression:
7269 case TemplateArgument::Template:
7270 case TemplateArgument::TemplateExpansion: return;
7271 case TemplateArgument::Type:
7272 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7273 return Visit(TagTy->getDecl());
7274 return;
7275 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7276 }
7277 llvm_unreachable("Invalid TemplateArgument::Kind!");
7278 }
7279
7280 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7281 {
7282 if (CTSD->getOwningModule())
7283 VisitDecl(CTSD);
7284 else
7285 VisitDecl(CTSD->getSpecializedTemplate());
7286 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7287 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7288 VisitTemplateArgument(*Arg);
7289 }
7290 }
7291 };
7292
7293 llvm::DenseSet<Module *> TopLevelModules;
7294 ModuleCollector m(TopLevelModules);
7295 m.Collect(D);
7296 std::string result;
7297 for (auto M : TopLevelModules) {
7298 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7299 // link declaration.
7300 if (!M->LinkLibraries.size())
7301 continue;
7302 // We have preloaded the Core module thus libCore.so
7303 if (M->Name == "Core" && skipCore)
7304 continue;
7305 assert(M->LinkLibraries.size() == 1);
7306 if (!result.empty())
7307 result += ' ';
7308 result += M->LinkLibraries[0].Library;
7309 }
7310 return result;
7311 }
7312 return {};
7313}
7314
7315////////////////////////////////////////////////////////////////////////////////
7316/// Get the list of shared libraries containing the code for class cls.
7317/// The first library in the list is the one containing the class, the
7318/// others are the libraries the first one depends on. Returns 0
7319/// in case the library is not found.
7320/// \param cls the name of the class
7321/// \param skipCore if true (default), remove "Core" from the returned list
7322
7323const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7324{
7325 if (fCxxModulesEnabled) {
7326 // Lock the interpreter mutex before interacting with cling.
7327 // TODO: Can we move this further deep? In principle the lock should be in
7328 // GetClassSharedLibsForModule, but it might be needed also for
7329 // getLookupHelper?
7331 llvm::StringRef className = cls;
7332 // If we get a class name containing lambda, we cannot parse it and we
7333 // can exit early.
7334 // FIXME: This works around a bug when we are instantiating a template
7335 // make_unique and the substitution fails. Seen in most of the dataframe
7336 // tests.
7337 if (className.contains("(lambda)"))
7338 return nullptr;
7339 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7340 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7341 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7342 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7343 if (!libs.empty()) {
7344 fAutoLoadLibStorage.push_back(libs);
7345 return fAutoLoadLibStorage.back().c_str();
7346 }
7347 }
7348
7349 if (!cls || !*cls) {
7350 return nullptr;
7351 }
7352 // lookup class to find list of libraries
7353 if (fMapfile) {
7354 TEnvRec* libs_record = nullptr;
7355 libs_record = fMapfile->Lookup(cls);
7356 if (libs_record) {
7357 const char* libs = libs_record->GetValue();
7358 return (*libs) ? libs : nullptr;
7359 }
7360 else {
7361 // Try the old format...
7362 TString c = TString("Library.") + cls;
7363 // convert "::" to "@@", we used "@@" because TEnv
7364 // considers "::" a terminator
7365 c.ReplaceAll("::", "@@");
7366 // convert "-" to " ", since class names may have
7367 // blanks and TEnv considers a blank a terminator
7368 c.ReplaceAll(" ", "-");
7369 // Use TEnv::Lookup here as the rootmap file must start with Library.
7370 // and do not support using any stars (so we do not need to waste time
7371 // with the search made by TEnv::GetValue).
7372 TEnvRec* libs_record = nullptr;
7373 libs_record = fMapfile->Lookup(c);
7374 if (libs_record) {
7375 const char* libs = libs_record->GetValue();
7376 return (*libs) ? libs : nullptr;
7377 }
7378 }
7379 }
7380 return nullptr;
7381}
7382
7383/// This interface returns a list of dependent libraries in the form:
7384/// lib libA.so libB.so libC.so. The first library is the library we are
7385/// searching dependencies for.
7386/// Note: In order to speed up the search, we display the dependencies of the
7387/// libraries which are not yet loaded. For instance, if libB.so was already
7388/// loaded the list would contain: lib libA.so libC.so.
7389static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7390 cling::Interpreter *interp,
7391 bool skipLoadedLibs = true)
7392{
7393 TString LibFullPath(lib);
7394 if (!llvm::sys::path::is_absolute(lib)) {
7395 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7396 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7397 return "";
7398 }
7399 } else {
7400 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7401 lib = llvm::sys::path::filename(lib).str();
7402 }
7403
7404 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7405 if (!ObjF) {
7406 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7407 return "";
7408 }
7409
7410 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7411
7412 std::set<string> DedupSet;
7413 std::string Result = lib + ' ';
7414 for (const auto &S : BinObjFile->symbols()) {
7415 uint32_t Flags = llvm::cantFail(S.getFlags());
7416 // Skip defined symbols: we have them.
7417 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7418 continue;
7419 // Skip undefined weak symbols: if we don't have them we won't need them.
7420 // `__gmon_start__` being a typical example.
7421 if (Flags & llvm::object::SymbolRef::SF_Weak)
7422 continue;
7423 llvm::Expected<StringRef> SymNameErr = S.getName();
7424 if (!SymNameErr) {
7425 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7426 continue;
7427 }
7428 llvm::StringRef SymName = SymNameErr.get();
7429 if (SymName.empty())
7430 continue;
7431
7432 if (BinObjFile->isELF()) {
7433 // Skip the symbols which are part of the C/C++ runtime and have a
7434 // fixed library version. See binutils ld VERSION. Those reside in
7435 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7436 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7437 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7438 continue;
7439
7440 // Those are 'weak undefined' symbols produced by gcc. We can
7441 // ignore them.
7442 // FIXME: It is unclear whether we can ignore all weak undefined
7443 // symbols:
7444 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7445 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7446 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7447 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7448 if (SymName == RegisterClasses ||
7449 SymName == RegisterCloneTable ||
7450 SymName == DeregisterCloneTable)
7451 continue;
7452 }
7453
7454 // If we can find the address of the symbol, we have loaded it. Skip.
7455 if (skipLoadedLibs) {
7456 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7457 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7458 continue;
7459 }
7460
7462 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7463 // The expected output is just filename without the full path, which
7464 // is not very accurate, because our Dyld implementation might find
7465 // a match in location a/b/c.so and if we return just c.so ROOT might
7466 // resolve it to y/z/c.so and there we might not be ABI compatible.
7467 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7468 if (!found.empty()) {
7469 std::string cand = llvm::sys::path::filename(found).str();
7470 if (!DedupSet.insert(cand).second)
7471 continue;
7472
7473 Result += cand + ' ';
7474 }
7475 }
7476
7477 return Result;
7478}
7479
7480static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7481{
7482 // Check if we have parsed a rootmap file.
7483 llvm::SmallString<256> rootmapName;
7484 if (!lib.starts_with("lib"))
7485 rootmapName.append("lib");
7486
7487 rootmapName.append(llvm::sys::path::filename(lib));
7488 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7489
7490 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7491 return true;
7492
7493 // Perform a last resort by dropping the lib prefix.
7494 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7495 if (rootmapNameNoLib.consume_front("lib"))
7496 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7497
7498 return false;
7499}
7500
7501static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7502{
7503 if (gCling->HasPCMForLibrary(lib.data()))
7504 return true;
7505
7506 return hasParsedRootmapForLibrary(lib);
7507}
7508
7509////////////////////////////////////////////////////////////////////////////////
7510/// Get the list a libraries on which the specified lib depends. The
7511/// returned string contains as first element the lib itself.
7512/// Returns 0 in case the lib does not exist or does not have
7513/// any dependencies. If useDyld is true, we iterate through all available
7514/// libraries and try to construct the dependency chain by resolving each
7515/// symbol.
7516
7517const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7518{
7519 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7520 return nullptr;
7521
7522 if (!hasParsedRootmapForLibrary(lib)) {
7523 llvm::SmallString<512> rootmapName(lib);
7524 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7525 if (llvm::sys::fs::exists(rootmapName)) {
7526 if (gDebug > 0)
7527 Info("Load", "loading %s", rootmapName.c_str());
7528 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7529 }
7530 }
7531
7532 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7533 if (gDebug > 0)
7534 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7535 }
7536
7537 if (useDyld) {
7538 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7539 if (!libs.empty()) {
7540 fAutoLoadLibStorage.push_back(libs);
7541 return fAutoLoadLibStorage.back().c_str();
7542 }
7543 }
7544
7545 if (!fMapfile || !lib || !lib[0]) {
7546 return nullptr;
7547 }
7548 TString libname(lib);
7549 Ssiz_t idx = libname.Last('.');
7550 if (idx != kNPOS) {
7551 libname.Remove(idx);
7552 }
7553 TEnvRec* rec;
7554 TIter next(fMapfile->GetTable());
7555 size_t len = libname.Length();
7556 while ((rec = (TEnvRec*) next())) {
7557 const char* libs = rec->GetValue();
7558 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7559 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7560 return libs;
7561 }
7562 }
7563 return nullptr;
7564}
7565
7566////////////////////////////////////////////////////////////////////////////////
7567/// If error messages are disabled, the interpreter should suppress its
7568/// failures and warning messages from stdout.
7569
7571{
7572#if defined(R__MUST_REVISIT)
7573#if R__MUST_REVISIT(6,2)
7574 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7575#endif
7576#endif
7577 return kTRUE;
7578}
7579
7580////////////////////////////////////////////////////////////////////////////////
7581/// If error messages are disabled, the interpreter should suppress its
7582/// failures and warning messages from stdout. Return the previous state.
7583
7585{
7586#if defined(R__MUST_REVISIT)
7587#if R__MUST_REVISIT(6,2)
7588 Warning("SetErrorMessages", "Interface not available yet.");
7589#endif
7590#endif
7592}
7593
7594////////////////////////////////////////////////////////////////////////////////
7595/// Refresh the list of include paths known to the interpreter and return it
7596/// with -I prepended.
7597
7599{
7601
7602 fIncludePath = "";
7603
7604 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7605 //false - no system header, true - with flags.
7606 fInterpreter->GetIncludePaths(includePaths, false, true);
7607 if (const size_t nPaths = includePaths.size()) {
7608 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7609
7610 for (size_t i = 0; i < nPaths; i += 2) {
7611 if (i)
7612 fIncludePath.Append(' ');
7613 fIncludePath.Append(includePaths[i].c_str());
7614
7615 if (includePaths[i] != "-I")
7616 fIncludePath.Append(' ');
7617 fIncludePath.Append('"');
7618 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7619 fIncludePath.Append('"');
7620 }
7621 }
7622
7623 return fIncludePath;
7624}
7625
7626////////////////////////////////////////////////////////////////////////////////
7627/// Return the directory containing CINT's stl cintdlls.
7628
7629const char* TCling::GetSTLIncludePath() const
7630{
7631 return "";
7632}
7633
7634//______________________________________________________________________________
7635// M I S C
7636//______________________________________________________________________________
7637
7638int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7639{
7640 // Interface to cling function
7641 return 0;
7642}
7643
7644////////////////////////////////////////////////////////////////////////////////
7645/// Interface to cling function
7646
7647int TCling::DisplayIncludePath(FILE *fout) const
7648{
7649 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7650
7651 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7652 //false - no system header, true - with flags.
7653 fInterpreter->GetIncludePaths(includePaths, false, true);
7654 if (const size_t nPaths = includePaths.size()) {
7655 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7656
7657 std::string allIncludes("include path:");
7658 for (size_t i = 0; i < nPaths; i += 2) {
7659 allIncludes += ' ';
7660 allIncludes += includePaths[i];
7661
7662 if (includePaths[i] != "-I")
7663 allIncludes += ' ';
7664 allIncludes += includePaths[i + 1];
7665 }
7666
7667 fprintf(fout, "%s\n", allIncludes.c_str());
7668 }
7669
7670 return 0;
7671}
7672
7673////////////////////////////////////////////////////////////////////////////////
7674/// Interface to cling function
7675
7676void* TCling::FindSym(const char* entry) const
7677{
7679 return fInterpreter->getAddressOfGlobal(entry);
7680}
7681
7682////////////////////////////////////////////////////////////////////////////////
7683/// Let the interpreter issue a generic error, and set its error state.
7684
7685void TCling::GenericError(const char* error) const
7686{
7687#if defined(R__MUST_REVISIT)
7688#if R__MUST_REVISIT(6,2)
7689 Warning("GenericError","Interface not available yet.");
7690#endif
7691#endif
7692}
7693
7694////////////////////////////////////////////////////////////////////////////////
7695/// This routines used to return the address of the internal wrapper
7696/// function (of the interpreter) that was used to call *all* the
7697/// interpreted functions that were bytecode compiled (no longer
7698/// interpreted line by line). In Cling, there is no such
7699/// wrapper function.
7700/// In practice this routines was use to decipher whether the
7701/// pointer returns by InterfaceMethod could be used to uniquely
7702/// represent the function. In Cling if the function is in a
7703/// useable state (its compiled version is available), this is
7704/// always the case.
7705/// See TClass::GetMethod.
7706
7708{
7709 return 0;
7710}
7711
7712////////////////////////////////////////////////////////////////////////////////
7713/// Interface to cling function
7714
7716{
7717#if defined(R__MUST_REVISIT)
7718#if R__MUST_REVISIT(6,2)
7719 Warning("GetSecurityError", "Interface not available yet.");
7720#endif
7721#endif
7722 return 0;
7723}
7724
7725////////////////////////////////////////////////////////////////////////////////
7726/// Load a source file or library called path into the interpreter.
7727
7728int TCling::LoadFile(const char* path) const
7729{
7730 // Modifying the interpreter state needs locking.
7732 cling::Interpreter::CompilationResult compRes;
7733 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7734 return compRes == cling::Interpreter::kFailure;
7735}
7736
7737////////////////////////////////////////////////////////////////////////////////
7738/// Load the declarations from text into the interpreter.
7739/// Note that this cannot be (top level) statements; text must contain
7740/// top level declarations.
7741/// Returns true on success, false on failure.
7742
7743Bool_t TCling::LoadText(const char* text) const
7744{
7745 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7746}
7747
7748////////////////////////////////////////////////////////////////////////////////
7749/// Interface to cling function
7750
7751const char* TCling::MapCppName(const char* name) const
7752{
7753 TTHREAD_TLS_DECL(std::string,buffer);
7755 return buffer.c_str(); // NOLINT
7756}
7757
7758////////////////////////////////////////////////////////////////////////////////
7759/// [Place holder for Mutex Lock]
7760/// Provide the interpreter with a way to
7761/// acquire a lock used to protect critical section
7762/// of its code (non-thread safe parts).
7763
7764void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7765{
7766 // nothing to do for now.
7767}
7768
7769////////////////////////////////////////////////////////////////////////////////
7770/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7771/// release a lock used to protect critical section
7772/// of its code (non-thread safe parts).
7773
7774void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7775{
7776 // nothing to do for now.
7777}
7778
7779////////////////////////////////////////////////////////////////////////////////
7780/// Returns if class AutoLoading is currently enabled.
7781
7783{
7784 if (IsFromRootCling())
7785 return false;
7786 if (!fClingCallbacks)
7787 return false;
7789}
7790
7791////////////////////////////////////////////////////////////////////////////////
7792/// Enable/Disable the AutoLoading of libraries.
7793/// Returns the old value, i.e whether it was enabled or not.
7794
7795int TCling::SetClassAutoLoading(int autoload) const
7796{
7797 // If no state change is required, exit early.
7798 // FIXME: In future we probably want to complain if we made a request which
7799 // was with the same state as before in order to catch programming errors.
7800 if ((bool) autoload == IsClassAutoLoadingEnabled())
7801 return autoload;
7802
7803 assert(fClingCallbacks && "We must have callbacks!");
7804 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7806 return oldVal;
7807}
7808
7809////////////////////////////////////////////////////////////////////////////////
7810/// Enable/Disable the Autoparsing of headers.
7811/// Returns the old value, i.e whether it was enabled or not.
7812
7814{
7815 bool oldVal = fHeaderParsingOnDemand;
7816 fHeaderParsingOnDemand = autoparse;
7817 return oldVal;
7818}
7819
7820////////////////////////////////////////////////////////////////////////////////
7821/// Suspend the Autoparsing of headers.
7822/// Returns the old value, i.e whether it was suspended or not.
7823
7830
7831////////////////////////////////////////////////////////////////////////////////
7832/// Set a callback to receive error messages.
7833
7835{
7836#if defined(R__MUST_REVISIT)
7837#if R__MUST_REVISIT(6,2)
7838 Warning("SetErrmsgcallback", "Interface not available yet.");
7839#endif
7840#endif
7841}
7842
7844{
7845 if (enable) {
7846 auto consumer = new TClingDelegateDiagnosticPrinter(
7847 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7848 fInterpreter->getCI()->getLangOpts(),
7849 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7850 if (Level == clang::DiagnosticsEngine::Warning) {
7851 ::Warning("cling", "%s", Info.c_str());
7852 } else if (Level == clang::DiagnosticsEngine::Error
7853 || Level == clang::DiagnosticsEngine::Fatal) {
7854 ::Error("cling", "%s", Info.c_str());
7855 } else {
7856 ::Info("cling", "%s", Info.c_str());
7857 }
7858 });
7859 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7860 } else {
7861 fInterpreter->replaceDiagnosticConsumer(nullptr);
7862 }
7863}
7864
7865
7866////////////////////////////////////////////////////////////////////////////////
7867/// Create / close a scope for temporaries. No-op for cling; use
7868/// cling::Value instead.
7869
7870void TCling::SetTempLevel(int val) const
7871{
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876int TCling::UnloadFile(const char* path) const
7877{
7878 // Modifying the interpreter state needs locking.
7880 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7881 std::string canonical = DLM->lookupLibrary(path);
7882 if (canonical.empty()) {
7883 canonical = path;
7884 }
7885 // Unload a shared library or a source file.
7886 cling::Interpreter::CompilationResult compRes;
7887 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7888 return compRes == cling::Interpreter::kFailure;
7889}
7890
7891std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7892 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7893}
7894
7895////////////////////////////////////////////////////////////////////////////////
7896/// The call to Cling's tab complition.
7897
7898void TCling::CodeComplete(const std::string& line, size_t& cursor,
7899 std::vector<std::string>& completions)
7900{
7901 fInterpreter->codeComplete(line, cursor, completions);
7902}
7903
7904////////////////////////////////////////////////////////////////////////////////
7905/// Get the interpreter value corresponding to the statement.
7907{
7909
7910 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7911 auto compRes = fInterpreter->evaluate(code, *V);
7912 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7913}
7914
7915////////////////////////////////////////////////////////////////////////////////
7916
7918{
7919 using namespace cling;
7920 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7922}
7923
7924////////////////////////////////////////////////////////////////////////////////
7925/// Register value as a temporary, extending its lifetime to that of the
7926/// interpreter. This is needed for TCling's compatibility interfaces
7927/// returning long - the address of the temporary objects.
7928/// As such, "simple" types don't need to be stored; they are returned by
7929/// value; only pointers / references / objects need to be stored.
7930
7931void TCling::RegisterTemporary(const cling::Value& value)
7932{
7933 if (value.isValid() && value.needsManagedAllocation()) {
7935 fTemporaries->push_back(value);
7936 }
7937}
7938
7939////////////////////////////////////////////////////////////////////////////////
7940/// If the interpreter encounters Name, check whether that is an object ROOT
7941/// could retrieve. To not re-read objects from disk, cache the name/object
7942/// pair for a given LookupCtx.
7943
7944TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7945{
7946 // The call to FindSpecialObject might induces any kind of use
7947 // of the interpreter ... (library loading, function calling, etc.)
7948 // ... and we _know_ we are in the middle of parsing, so let's make
7949 // sure to save the state and then restore it.
7950
7951 if (gDirectory) {
7952 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7953 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7954 auto iSpecObj = iSpecObjMap->second.find(Name);
7955 if (iSpecObj != iSpecObjMap->second.end()) {
7956 LookupCtx = gDirectory;
7957 return iSpecObj->second;
7958 }
7959 }
7960 }
7961
7962 // Save state of the PP
7963 Sema &SemaR = fInterpreter->getSema();
7964 ASTContext& C = SemaR.getASTContext();
7965 Preprocessor &PP = SemaR.getPreprocessor();
7966 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7967 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7968 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7969 // After we have saved the token reset the current one to something which
7970 // is safe (semi colon usually means empty decl)
7971 Token& Tok = const_cast<Token&>(P.getCurToken());
7972 Tok.setKind(tok::semi);
7973
7974 // We can't PushDeclContext, because we go up and the routine that pops
7975 // the DeclContext assumes that we drill down always.
7976 // We have to be on the global context. At that point we are in a
7977 // wrapper function so the parent context must be the global.
7978 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7979 SemaR.TUScope);
7980
7981 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7982 if (specObj) {
7983 if (!LookupCtx) {
7984 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7985 } else {
7986 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7987 }
7988 }
7989 return specObj;
7990}
7991
7992////////////////////////////////////////////////////////////////////////////////
7993/// Inject function as a friend into klass.
7994/// With function being f in void f() {new N::PrivKlass(); } this enables
7995/// I/O of non-public classes.
7996
7997void TCling::AddFriendToClass(clang::FunctionDecl* function,
7998 clang::CXXRecordDecl* klass) const
7999{
8000 using namespace clang;
8001 ASTContext& Ctx = klass->getASTContext();
8002 FriendDecl::FriendUnion friendUnion(function);
8003 // one dummy object for the source location
8004 SourceLocation sl;
8005 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
8006 klass->pushFriendDecl(friendDecl);
8007}
8008
8009//______________________________________________________________________________
8010//
8011// DeclId getter.
8012//
8013
8014////////////////////////////////////////////////////////////////////////////////
8015/// Return a unique identifier of the declaration represented by the
8016/// CallFunc
8017
8019{
8020 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
8021 return nullptr;
8022}
8023
8024////////////////////////////////////////////////////////////////////////////////
8025/// Return a (almost) unique identifier of the declaration represented by the
8026/// ClassInfo. In ROOT, this identifier can point to more than one TClass
8027/// when the underlying class is a template instance involving one of the
8028/// opaque typedef.
8029
8031{
8032 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
8033 return nullptr;
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037/// Return a unique identifier of the declaration represented by the
8038/// MethodInfo
8039
8041{
8042 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
8043 return nullptr;
8044}
8045
8046////////////////////////////////////////////////////////////////////////////////
8047/// Return a unique identifier of the declaration represented by the
8048/// MethodInfo
8049
8051{
8052 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
8053 return nullptr;
8054}
8055
8056////////////////////////////////////////////////////////////////////////////////
8057/// Return a unique identifier of the declaration represented by the
8058/// TypedefInfo
8059
8061{
8062 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
8063 return nullptr;
8064}
8065
8066//______________________________________________________________________________
8067//
8068// CallFunc interface
8069//
8070
8071////////////////////////////////////////////////////////////////////////////////
8072
8073void TCling::CallFunc_Delete(CallFunc_t* func) const
8074{
8075 delete (TClingCallFunc*) func;
8076}
8077
8078////////////////////////////////////////////////////////////////////////////////
8079
8080void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
8081{
8082 TClingCallFunc* f = (TClingCallFunc*) func;
8083 f->Exec(address);
8084}
8085
8086////////////////////////////////////////////////////////////////////////////////
8087
8088void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
8089{
8090 TClingCallFunc* f = (TClingCallFunc*) func;
8091 f->Exec(address, &val);
8092}
8093
8094////////////////////////////////////////////////////////////////////////////////
8095
8096void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
8097{
8098 TClingCallFunc* f = (TClingCallFunc*) func;
8099 f->ExecWithReturn(address, ret);
8100}
8101
8102////////////////////////////////////////////////////////////////////////////////
8103
8104void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
8105 const void* args[] /*=0*/,
8106 int nargs /*=0*/,
8107 void* ret/*=0*/) const
8108{
8109 TClingCallFunc* f = (TClingCallFunc*) func;
8110 f->ExecWithArgsAndReturn(address, args, nargs, ret);
8111}
8112
8113////////////////////////////////////////////////////////////////////////////////
8114
8115Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
8116{
8117 TClingCallFunc* f = (TClingCallFunc*) func;
8118 return f->ExecInt(address);
8119}
8120
8121////////////////////////////////////////////////////////////////////////////////
8122
8123Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
8124{
8125 TClingCallFunc* f = (TClingCallFunc*) func;
8126 return f->ExecInt64(address);
8127}
8128
8129////////////////////////////////////////////////////////////////////////////////
8130
8131Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
8132{
8133 TClingCallFunc* f = (TClingCallFunc*) func;
8134 return f->ExecDouble(address);
8135}
8136
8137////////////////////////////////////////////////////////////////////////////////
8138
8139CallFunc_t* TCling::CallFunc_Factory() const
8140{
8142 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
8143}
8144
8145////////////////////////////////////////////////////////////////////////////////
8146
8147CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
8148{
8149 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
8150}
8151
8152////////////////////////////////////////////////////////////////////////////////
8153
8154MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
8155{
8156 TClingCallFunc* f = (TClingCallFunc*) func;
8157 return (MethodInfo_t*) f->FactoryMethod();
8158}
8159
8160////////////////////////////////////////////////////////////////////////////////
8161
8162void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
8163{
8164 TClingCallFunc* f = (TClingCallFunc*) func;
8165 f->IgnoreExtraArgs(ignore);
8166}
8167
8168////////////////////////////////////////////////////////////////////////////////
8169
8170void TCling::CallFunc_Init(CallFunc_t* func) const
8171{
8173 TClingCallFunc* f = (TClingCallFunc*) func;
8174 f->Init();
8175}
8176
8177////////////////////////////////////////////////////////////////////////////////
8178
8179bool TCling::CallFunc_IsValid(CallFunc_t* func) const
8180{
8181 TClingCallFunc* f = (TClingCallFunc*) func;
8182 return f->IsValid();
8183}
8184
8185////////////////////////////////////////////////////////////////////////////////
8186
8188TCling::CallFunc_IFacePtr(CallFunc_t * func) const
8189{
8190 TClingCallFunc* f = (TClingCallFunc*) func;
8191 return f->IFacePtr();
8192}
8193
8194////////////////////////////////////////////////////////////////////////////////
8195
8196void TCling::CallFunc_ResetArg(CallFunc_t* func) const
8197{
8198 TClingCallFunc* f = (TClingCallFunc*) func;
8199 f->ResetArg();
8200}
8201
8202////////////////////////////////////////////////////////////////////////////////
8203
8204void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
8205{
8206 TClingCallFunc* f = (TClingCallFunc*) func;
8207 f->SetArg(param);
8208}
8209
8210////////////////////////////////////////////////////////////////////////////////
8211
8212void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
8213{
8214 TClingCallFunc* f = (TClingCallFunc*) func;
8215 f->SetArg(param);
8216}
8217
8218////////////////////////////////////////////////////////////////////////////////
8219
8220void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
8221{
8222 TClingCallFunc* f = (TClingCallFunc*) func;
8223 f->SetArg(param);
8224}
8225
8226////////////////////////////////////////////////////////////////////////////////
8227
8228void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
8229{
8230 TClingCallFunc* f = (TClingCallFunc*) func;
8231 f->SetArg(param);
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235
8236void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8237{
8238 TClingCallFunc* f = (TClingCallFunc*) func;
8239 f->SetArg(param);
8240}
8241
8242////////////////////////////////////////////////////////////////////////////////
8243
8244void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8245{
8246 TClingCallFunc* f = (TClingCallFunc*) func;
8247 f->SetArg(param);
8248}
8249
8250////////////////////////////////////////////////////////////////////////////////
8251
8252void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8253{
8254 TClingCallFunc* f = (TClingCallFunc*) func;
8255 f->SetArgArray(paramArr, nparam);
8256}
8257
8258////////////////////////////////////////////////////////////////////////////////
8259
8260void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8261{
8262 TClingCallFunc* f = (TClingCallFunc*) func;
8263 f->SetArgs(param);
8264}
8265
8266////////////////////////////////////////////////////////////////////////////////
8267
8268void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8269{
8270 TClingCallFunc* f = (TClingCallFunc*) func;
8271 TClingClassInfo* ci = (TClingClassInfo*) info;
8272 f->SetFunc(ci, method, params, offset);
8273}
8274
8275////////////////////////////////////////////////////////////////////////////////
8276
8277void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8278{
8279 TClingCallFunc* f = (TClingCallFunc*) func;
8280 TClingClassInfo* ci = (TClingClassInfo*) info;
8281 f->SetFunc(ci, method, params, objectIsConst, offset);
8282}
8283////////////////////////////////////////////////////////////////////////////////
8284
8285void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8286{
8287 TClingCallFunc* f = (TClingCallFunc*) func;
8288 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8289 f->SetFunc(minfo);
8290}
8291
8292////////////////////////////////////////////////////////////////////////////////
8293/// Interface to cling function
8294
8295void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8296{
8297 TClingCallFunc* f = (TClingCallFunc*) func;
8298 TClingClassInfo* ci = (TClingClassInfo*) info;
8299 f->SetFuncProto(ci, method, proto, offset, mode);
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303/// Interface to cling function
8304
8305void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8306{
8307 TClingCallFunc* f = (TClingCallFunc*) func;
8308 TClingClassInfo* ci = (TClingClassInfo*) info;
8309 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8310}
8311
8312////////////////////////////////////////////////////////////////////////////////
8313/// Interface to cling function
8314
8315void 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
8316{
8317 TClingCallFunc* f = (TClingCallFunc*) func;
8318 TClingClassInfo* ci = (TClingClassInfo*) info;
8319 llvm::SmallVector<clang::QualType, 4> funcProto;
8320 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8321 iter != end; ++iter) {
8322 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8323 }
8324 f->SetFuncProto(ci, method, funcProto, offset, mode);
8325}
8326
8327////////////////////////////////////////////////////////////////////////////////
8328/// Interface to cling function
8329
8330void 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
8331{
8332 TClingCallFunc* f = (TClingCallFunc*) func;
8333 TClingClassInfo* ci = (TClingClassInfo*) info;
8334 llvm::SmallVector<clang::QualType, 4> funcProto;
8335 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8336 iter != end; ++iter) {
8337 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8338 }
8339 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8340}
8341
8342std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8343{
8344 TClingCallFunc *f = (TClingCallFunc *)func;
8345 std::string wrapper_name;
8346 std::string wrapper;
8347 f->get_wrapper_code(wrapper_name, wrapper);
8348 return wrapper;
8349}
8350
8351//______________________________________________________________________________
8352//
8353// ClassInfo interface
8354//
8355
8356////////////////////////////////////////////////////////////////////////////////
8357
8358size_t TCling::ClassInfo_AlignOf(ClassInfo_t *cinfo) const
8359{
8360 TClingClassInfo *TClinginfo = (TClingClassInfo *)cinfo;
8361 return TClinginfo->GetAlignOf();
8362}
8363
8364////////////////////////////////////////////////////////////////////////////////
8365/// Return true if the entity pointed to by 'declid' is declared in
8366/// the context described by 'info'. If info is null, look into the
8367/// global scope (translation unit scope).
8368
8369Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8370{
8371 if (!declid)
8372 return kFALSE;
8373
8374 const clang::DeclContext *ctxt = nullptr;
8375 if (info) {
8376 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8377 } else {
8378 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8379 }
8380 if (!ctxt)
8381 return kFALSE;
8382
8383 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8384 if (!decl)
8385 return kFALSE;
8386
8387 const clang::DeclContext *declDC = decl->getDeclContext();
8388 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8389 while (true) {
8390 if (declDC->isTransparentContext()) {
8391 declDC = declDC->getParent();
8392 continue;
8393 }
8394 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8395 if (declRD->isAnonymousStructOrUnion()) {
8396 declDC = declRD->getParent();
8397 continue;
8398 }
8399 }
8400 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8401 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8402 declDC = declNS->getParent();
8403 continue;
8404 }
8405 }
8406 break;
8407 }
8408
8409 return declDC->Equals(ctxt);
8410}
8411
8412////////////////////////////////////////////////////////////////////////////////
8413
8415{
8416 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8417 return TClinginfo->ClassProperty();
8418}
8419
8420////////////////////////////////////////////////////////////////////////////////
8421
8422void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8423{
8424 delete (TClingClassInfo*) cinfo;
8425}
8426
8427////////////////////////////////////////////////////////////////////////////////
8428
8429void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8430{
8431 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8432 TClinginfo->Delete(arena,*fNormalizedCtxt);
8433}
8434
8435////////////////////////////////////////////////////////////////////////////////
8436
8437void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8438{
8439 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8440 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8441}
8442
8443////////////////////////////////////////////////////////////////////////////////
8444
8445void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8446{
8447 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8448 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8449}
8450
8451////////////////////////////////////////////////////////////////////////////////
8452
8453ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8454{
8456 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8457}
8458
8459////////////////////////////////////////////////////////////////////////////////
8460
8461ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8462{
8463 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8464}
8465
8466////////////////////////////////////////////////////////////////////////////////
8467
8468ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8469{
8471 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8472}
8473
8474ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8475{
8477 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8478}
8479
8480
8481////////////////////////////////////////////////////////////////////////////////
8482
8483int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8484{
8485 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8486 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8487}
8488
8489////////////////////////////////////////////////////////////////////////////////
8490
8491bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8492{
8493 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8495}
8496
8497////////////////////////////////////////////////////////////////////////////////
8498
8499bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8500{
8501 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8502 return TClinginfo->HasMethod(name);
8503}
8504
8505////////////////////////////////////////////////////////////////////////////////
8506
8507void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8508{
8510 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8511 TClinginfo->Init(name);
8512}
8513
8514////////////////////////////////////////////////////////////////////////////////
8515
8516void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8517{
8519 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8520 TClinginfo->Init(tagnum);
8521}
8522
8523////////////////////////////////////////////////////////////////////////////////
8524
8525bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8526{
8527 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8528 return TClinginfo->IsBase(name);
8529}
8530
8531////////////////////////////////////////////////////////////////////////////////
8532
8533bool TCling::ClassInfo_IsEnum(const char* name) const
8534{
8536}
8537
8538////////////////////////////////////////////////////////////////////////////////
8539
8541{
8542 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8543 return TClinginfo->IsScopedEnum();
8544}
8545
8546
8547////////////////////////////////////////////////////////////////////////////////
8548
8550{
8551 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8552 return TClinginfo->GetUnderlyingType();
8553}
8554
8555
8556////////////////////////////////////////////////////////////////////////////////
8557
8558bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8559{
8560 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8561 return TClinginfo->IsLoaded();
8562}
8563
8564////////////////////////////////////////////////////////////////////////////////
8565
8566bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8567{
8568 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8569 return TClinginfo->IsValid();
8570}
8571
8572////////////////////////////////////////////////////////////////////////////////
8573
8574bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8575{
8576 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8577 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8578}
8579
8580////////////////////////////////////////////////////////////////////////////////
8581
8582bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8583{
8584 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8585 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8586}
8587
8588////////////////////////////////////////////////////////////////////////////////
8589
8590int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8591{
8592 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8593 return TClinginfo->Next();
8594}
8595
8596////////////////////////////////////////////////////////////////////////////////
8597
8598void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8599{
8600 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8601 return TClinginfo->New(*fNormalizedCtxt);
8602}
8603
8604////////////////////////////////////////////////////////////////////////////////
8605
8606void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8607{
8608 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8609 return TClinginfo->New(n,*fNormalizedCtxt);
8610}
8611
8612////////////////////////////////////////////////////////////////////////////////
8613
8614void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8615{
8616 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8617 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8618}
8619
8620////////////////////////////////////////////////////////////////////////////////
8621
8622void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8623{
8624 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8625 return TClinginfo->New(arena,*fNormalizedCtxt);
8626}
8627
8628////////////////////////////////////////////////////////////////////////////////
8629
8630Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8631{
8632 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8633 return TClinginfo->Property();
8634}
8635
8636////////////////////////////////////////////////////////////////////////////////
8637
8638int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8639{
8640 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8641 return TClinginfo->Size();
8642}
8643
8644////////////////////////////////////////////////////////////////////////////////
8645
8646Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8647{
8648 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8649 return TClinginfo->Tagnum();
8650}
8651
8652////////////////////////////////////////////////////////////////////////////////
8653
8654const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8655{
8656 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8657 return TClinginfo->FileName();
8658}
8659
8660////////////////////////////////////////////////////////////////////////////////
8661
8662const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8663{
8664 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8665 TTHREAD_TLS_DECL(std::string,output);
8666 TClinginfo->FullName(output,*fNormalizedCtxt);
8667 return output.c_str(); // NOLINT
8668}
8669
8670////////////////////////////////////////////////////////////////////////////////
8671
8672const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8673{
8674 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8675 return TClinginfo->Name();
8676}
8677
8678////////////////////////////////////////////////////////////////////////////////
8679
8680const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8681{
8682 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8683 return TClinginfo->Title();
8684}
8685
8686////////////////////////////////////////////////////////////////////////////////
8687
8688const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8689{
8690 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8691 return TClinginfo->TmpltName();
8692}
8693
8694
8695
8696//______________________________________________________________________________
8697//
8698// BaseClassInfo interface
8699//
8700
8701////////////////////////////////////////////////////////////////////////////////
8702
8703void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8704{
8705 delete(TClingBaseClassInfo*) bcinfo;
8706}
8707
8708////////////////////////////////////////////////////////////////////////////////
8709
8710BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8711{
8713 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8714 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8715}
8716
8717////////////////////////////////////////////////////////////////////////////////
8718
8719BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8720 ClassInfo_t* base) const
8721{
8723 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8724 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8725 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8726}
8727
8728////////////////////////////////////////////////////////////////////////////////
8729
8730int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8731{
8732 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8733 return TClinginfo->Next();
8734}
8735
8736////////////////////////////////////////////////////////////////////////////////
8737
8738int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8739{
8740 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8741 return TClinginfo->Next(onlyDirect);
8742}
8743
8744////////////////////////////////////////////////////////////////////////////////
8745
8746Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8747{
8748 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8749 return TClinginfo->Offset(address, isDerivedObject);
8750}
8751
8752////////////////////////////////////////////////////////////////////////////////
8753
8754Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8755{
8756 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8757 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8758 // Offset to the class itself.
8759 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8760 return 0;
8761 }
8762 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8763}
8764
8765////////////////////////////////////////////////////////////////////////////////
8766
8767Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8768{
8769 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8770 return TClinginfo->Property();
8771}
8772
8773////////////////////////////////////////////////////////////////////////////////
8774
8775ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8776{
8777 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8778 return (ClassInfo_t *)TClinginfo->GetBase();
8779}
8780
8781////////////////////////////////////////////////////////////////////////////////
8782
8783Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8784{
8785 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8786 return TClinginfo->Tagnum();
8787}
8788
8789////////////////////////////////////////////////////////////////////////////////
8790
8791const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8792{
8793 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8794 TTHREAD_TLS_DECL(std::string,output);
8795 TClinginfo->FullName(output,*fNormalizedCtxt);
8796 return output.c_str(); // NOLINT
8797}
8798
8799////////////////////////////////////////////////////////////////////////////////
8800
8801const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8802{
8803 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8804 return TClinginfo->Name();
8805}
8806
8807////////////////////////////////////////////////////////////////////////////////
8808
8809const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8810{
8811 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8812 return TClinginfo->TmpltName();
8813}
8814
8815//______________________________________________________________________________
8816//
8817// DataMemberInfo interface
8818//
8819
8820////////////////////////////////////////////////////////////////////////////////
8821
8822int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8823{
8824 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8825 return TClinginfo->ArrayDim();
8826}
8827
8828////////////////////////////////////////////////////////////////////////////////
8829
8830void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8831{
8832 delete(TClingDataMemberInfo*) dminfo;
8833}
8834
8835////////////////////////////////////////////////////////////////////////////////
8836
8837DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8838{
8840 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8841 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8842}
8843
8844////////////////////////////////////////////////////////////////////////////////
8845
8846DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8847{
8849 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8850 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8851 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8852}
8853
8854////////////////////////////////////////////////////////////////////////////////
8855
8856DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8857{
8858 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8859 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8860}
8861
8862////////////////////////////////////////////////////////////////////////////////
8863
8864bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8865{
8866 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8867 return TClinginfo->IsValid();
8868}
8869
8870////////////////////////////////////////////////////////////////////////////////
8871
8872int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8873{
8874 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8875 return TClinginfo->MaxIndex(dim);
8876}
8877
8878////////////////////////////////////////////////////////////////////////////////
8879
8880int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8881{
8882 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8883 return TClinginfo->Next();
8884}
8885
8886////////////////////////////////////////////////////////////////////////////////
8887
8888Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8889{
8890 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8891 return TClinginfo->Offset();
8892}
8893
8894////////////////////////////////////////////////////////////////////////////////
8895
8896Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8897{
8898 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8899 return TClinginfo->Property();
8900}
8901
8902////////////////////////////////////////////////////////////////////////////////
8903
8904Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8905{
8906 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8907 return TClinginfo->TypeProperty();
8908}
8909
8910////////////////////////////////////////////////////////////////////////////////
8911
8912int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8913{
8914 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8915 return TClinginfo->TypeSize();
8916}
8917
8918////////////////////////////////////////////////////////////////////////////////
8919
8920const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8921{
8922 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8923 return TClinginfo->TypeName();
8924}
8925
8926////////////////////////////////////////////////////////////////////////////////
8927
8928const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8929{
8930 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8931 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8932}
8933
8934////////////////////////////////////////////////////////////////////////////////
8935
8936const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8937{
8938 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8939 return TClinginfo->Name();
8940}
8941
8942////////////////////////////////////////////////////////////////////////////////
8943
8944const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8945{
8946 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8947 return TClinginfo->Title();
8948}
8949
8950////////////////////////////////////////////////////////////////////////////////
8951
8952const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8953{
8954 TTHREAD_TLS_DECL(std::string,result);
8955
8956 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8957 result = TClinginfo->ValidArrayIndex().str();
8958 return result.c_str(); // NOLINT
8959}
8960
8961////////////////////////////////////////////////////////////////////////////////
8962
8963void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8964{
8965 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8966 ASTContext &C = decl->getASTContext();
8967 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8968}
8969
8970//______________________________________________________________________________
8971//
8972// Function Template interface
8973//
8974
8975////////////////////////////////////////////////////////////////////////////////
8976
8977static void ConstructorName(std::string &name, const clang::Decl *decl,
8978 cling::Interpreter &interp,
8979 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8980{
8981 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8982 if (!td) return;
8983
8984 clang::QualType qualType = td->getASTContext().getTypeDeclType(td);
8985 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8986 unsigned int level = 0;
8987 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8988 if (name[cursor] == '>') ++level;
8989 else if (name[cursor] == '<' && level) --level;
8990 else if (level == 0 && name[cursor] == ':') {
8991 name.erase(0,cursor+1);
8992 break;
8993 }
8994 }
8995}
8996
8997////////////////////////////////////////////////////////////////////////////////
8998
8999void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
9000{
9001 output.clear();
9002
9003 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
9004 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
9005 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
9006 }
9007 if (!FD) {
9008 Error("GetFunctionName", "NULL Decl!");
9009 return;
9010 }
9011
9012 // For using-decls, show "Derived", not "Base", i.e. use the
9013 // name of the decl context of the UsingShadowDecl (aka `decl`)
9014 // not the name of FD's decl context.
9015 if (llvm::isa<clang::CXXConstructorDecl>(FD))
9016 {
9018
9019 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
9020 {
9022 output.insert(output.begin(), '~');
9023 } else {
9024 llvm::raw_string_ostream stream(output);
9025 auto printPolicy = decl->getASTContext().getPrintingPolicy();
9026 // Don't trigger fopen of the source file to count lines:
9027 printPolicy.AnonymousTagLocations = false;
9028 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
9029 }
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033/// Return a unique identifier of the declaration represented by the
9034/// FuncTempInfo
9035
9037{
9038 return (DeclId_t)info;
9039}
9040
9041////////////////////////////////////////////////////////////////////////////////
9042/// Delete the FuncTempInfo_t
9043
9044void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
9045{
9046 // Currently the address of ft_info is actually the decl itself,
9047 // so we have nothing to do.
9048}
9049
9050////////////////////////////////////////////////////////////////////////////////
9051/// Construct a FuncTempInfo_t
9052
9053FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
9054{
9055 // Currently the address of ft_info is actually the decl itself,
9056 // so we have nothing to do.
9057
9058 return (FuncTempInfo_t*)const_cast<void*>(declid);
9059}
9060
9061////////////////////////////////////////////////////////////////////////////////
9062/// Construct a FuncTempInfo_t
9063
9064FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
9065{
9066 // Currently the address of ft_info is actually the decl itself,
9067 // so we have nothing to do.
9068
9069 return (FuncTempInfo_t*)ft_info;
9070}
9071
9072////////////////////////////////////////////////////////////////////////////////
9073/// Check validity of a FuncTempInfo_t
9074
9075Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
9076{
9077 // Currently the address of ft_info is actually the decl itself,
9078 // so we have nothing to do.
9079
9080 return t_info != nullptr;
9081}
9082
9083////////////////////////////////////////////////////////////////////////////////
9084/// Return the maximum number of template arguments of the
9085/// function template described by ft_info.
9086
9087UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
9088{
9089 if (!ft_info) return 0;
9090 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9091 return ft->getTemplateParameters()->size();
9092}
9093
9094////////////////////////////////////////////////////////////////////////////////
9095/// Return the number of required template arguments of the
9096/// function template described by ft_info.
9097
9099{
9100 if (!ft_info) return 0;
9101 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9102 return ft->getTemplateParameters()->getMinRequiredArguments();
9103}
9104
9105////////////////////////////////////////////////////////////////////////////////
9106/// Return the property of the function template.
9107
9108Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
9109{
9110 if (!ft_info) return 0;
9111
9112 long property = 0L;
9113 property |= kIsCompiled;
9114
9115 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9116
9117 switch (ft->getAccess()) {
9118 case clang::AS_public:
9119 property |= kIsPublic;
9120 break;
9121 case clang::AS_protected:
9122 property |= kIsProtected;
9123 break;
9124 case clang::AS_private:
9125 property |= kIsPrivate;
9126 break;
9127 case clang::AS_none:
9128 if (ft->getDeclContext()->isNamespace())
9130 break;
9131 default:
9132 // IMPOSSIBLE
9133 assert(false && "Unexpected value for the access property value in Clang");
9134 break;
9135 }
9136
9137 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9138
9139 if (fd && fd->getStorageClass() == clang::SC_Static)
9140 property |= kIsStatic;
9141
9142 if (const clang::CXXMethodDecl *md =
9143 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
9144 if (md->getMethodQualifiers().hasConst()) {
9145 property |= kIsConstant | kIsConstMethod;
9146 }
9147 if (md->isVirtual()) {
9148 property |= kIsVirtual;
9149 }
9150 if (md->isPureVirtual()) {
9151 property |= kIsPureVirtual;
9152 }
9153 if (const clang::CXXConstructorDecl *cd =
9154 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
9155 if (cd->isExplicit()) {
9156 property |= kIsExplicit;
9157 }
9158 }
9159 else if (const clang::CXXConversionDecl *cd =
9160 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
9161 if (cd->isExplicit()) {
9162 property |= kIsExplicit;
9163 }
9164 }
9165 }
9166 return property;
9167}
9168
9169////////////////////////////////////////////////////////////////////////////////
9170/// Return the property not already defined in Property
9171/// See TDictionary's EFunctionProperty
9172
9173Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
9174{
9175 if (!ft_info) return 0;
9176
9177 long property = 0L;
9178 property |= kIsCompiled;
9179
9180 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9181 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9182
9183 if (fd->isOverloadedOperator())
9185 if (llvm::isa<clang::CXXConversionDecl>(fd))
9187 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9189 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9191 if (fd->isInlined())
9193 return property;
9194}
9195
9196////////////////////////////////////////////////////////////////////////////////
9197/// Return the name of this function template.
9198
9199void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
9200{
9201 output.Clear();
9202 if (!ft_info) return;
9203 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9204 std::string buf;
9205 GetFunctionName(ft->getTemplatedDecl(), buf);
9206 output = buf;
9207}
9208
9209////////////////////////////////////////////////////////////////////////////////
9210/// Return the comments associates with this function template.
9211
9212void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
9213{
9214 output.Clear();
9215 if (!ft_info) return;
9216 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9217
9218 // Iterate over the redeclarations, we can have multiple definitions in the
9219 // redecl chain (came from merging of pcms).
9220 if (const RedeclarableTemplateDecl *AnnotFD
9221 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
9222 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9223 output = A->getAnnotation().str();
9224 return;
9225 }
9226 }
9227 if (!ft->isFromASTFile()) {
9228 // Try to get the comment from the header file if present
9229 // but not for decls from AST file, where rootcling would have
9230 // created an annotation
9231 output = ROOT::TMetaUtils::GetComment(*ft).str();
9232 }
9233}
9234
9235
9236//______________________________________________________________________________
9237//
9238// MethodInfo interface
9239//
9240
9241////////////////////////////////////////////////////////////////////////////////
9242/// Interface to cling function
9243
9244void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9245{
9246 delete(TClingMethodInfo*) minfo;
9247}
9248
9249////////////////////////////////////////////////////////////////////////////////
9250
9251void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9252{
9253 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9254 // The next call locks the interpreter mutex.
9255 info->CreateSignature(signature);
9256}
9257
9258////////////////////////////////////////////////////////////////////////////////
9259
9260MethodInfo_t* TCling::MethodInfo_Factory() const
9261{
9263 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9264}
9265
9266////////////////////////////////////////////////////////////////////////////////
9267
9268MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9269{
9271 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275
9276MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9277{
9278 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9280 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9281}
9282
9283////////////////////////////////////////////////////////////////////////////////
9284
9285MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9286{
9287 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9288}
9289
9290////////////////////////////////////////////////////////////////////////////////
9291
9292void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9293{
9294 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9295 // The next call locks the interpreter mutex.
9296 return info->InterfaceMethod();
9297}
9298
9299////////////////////////////////////////////////////////////////////////////////
9300
9301bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9302{
9303 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9304 return info->IsValid();
9305}
9306
9307////////////////////////////////////////////////////////////////////////////////
9308
9309int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9310{
9311 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9312 return info->NArg();
9313}
9314
9315////////////////////////////////////////////////////////////////////////////////
9316
9317int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9318{
9319 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9320 return info->NDefaultArg();
9321}
9322
9323////////////////////////////////////////////////////////////////////////////////
9324
9325int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9326{
9327 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9328 return info->Next();
9329}
9330
9331////////////////////////////////////////////////////////////////////////////////
9332
9333Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9334{
9335 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9336 // The next call locks the interpreter mutex.
9337 return info->Property();
9338}
9339
9340////////////////////////////////////////////////////////////////////////////////
9341
9343{
9344 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9345 // The next call locks the interpreter mutex.
9346 return info->ExtraProperty();
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350
9351TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9352{
9353 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9354 // The next call locks the interpreter mutex.
9355 return (TypeInfo_t*)info->Type();
9356}
9357
9358////////////////////////////////////////////////////////////////////////////////
9359
9360const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9361{
9362 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9363 TTHREAD_TLS_DECL(TString, mangled_name);
9364 // The next call locks the interpreter mutex.
9365 mangled_name = info->GetMangledName();
9366 return mangled_name;
9367}
9368
9369////////////////////////////////////////////////////////////////////////////////
9370
9371const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9372{
9373 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9374 // The next call locks the interpreter mutex.
9375 return info->GetPrototype();
9376}
9377
9378////////////////////////////////////////////////////////////////////////////////
9379
9380const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9381{
9382 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9383 // The next call locks the interpreter mutex.
9384 return info->Name();
9385}
9386
9387////////////////////////////////////////////////////////////////////////////////
9388
9389const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9390{
9391 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9392 // The next call locks the interpreter mutex.
9393 return info->TypeName();
9394}
9395
9396////////////////////////////////////////////////////////////////////////////////
9397
9398std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9399{
9400 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9401 // The next part locks the interpreter mutex.
9402 if (info && info->IsValid())
9403 return info->Type()->NormalizedName(*fNormalizedCtxt);
9404 else
9405 return "";
9406}
9407
9408////////////////////////////////////////////////////////////////////////////////
9409
9410const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9411{
9412 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9413 // The next call locks the interpreter mutex.
9414 return info->Title();
9415}
9416
9417////////////////////////////////////////////////////////////////////////////////
9418
9420{
9421 if (func) {
9422 return MethodInfo_MethodCallReturnType(func->fInfo);
9423 } else {
9424 return EReturnType::kOther;
9425 }
9426}
9427
9428////////////////////////////////////////////////////////////////////////////////
9429
9431{
9432 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9433 if (info && info->IsValid()) {
9434 TClingTypeInfo *typeinfo = info->Type();
9435 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9436 if (QT->isEnumeralType()) {
9437 return EReturnType::kLong;
9438 } else if (QT->isPointerType()) {
9439 // Look for char*
9440 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9441 if ( QT->isCharType() ) {
9442 return EReturnType::kString;
9443 } else {
9444 return EReturnType::kOther;
9445 }
9446 } else if ( QT->isFloatingType() ) {
9447 int sz = typeinfo->Size();
9448 if (sz == 4 || sz == 8) {
9449 // Support only float and double.
9450 return EReturnType::kDouble;
9451 } else {
9452 return EReturnType::kOther;
9453 }
9454 } else if ( QT->isIntegerType() ) {
9455 int sz = typeinfo->Size();
9456 if (sz <= 8) {
9457 // Support only up to long long ... but
9458 // FIXME the TMethodCall::Execute only
9459 // return long (4 bytes) ...
9460 // The v5 implementation of TMethodCall::ReturnType
9461 // was not making the distinction so we let it go
9462 // as is for now, but we really need to upgrade
9463 // TMethodCall::Execute ...
9464 return EReturnType::kLong;
9465 } else {
9466 return EReturnType::kOther;
9467 }
9468 } else {
9469 return EReturnType::kOther;
9470 }
9471 } else {
9472 return EReturnType::kOther;
9473 }
9474}
9475
9476//______________________________________________________________________________
9477//
9478// MethodArgInfo interface
9479//
9480
9481////////////////////////////////////////////////////////////////////////////////
9482
9483void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9484{
9485 delete(TClingMethodArgInfo*) marginfo;
9486}
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9490MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9491{
9493 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9494}
9495
9496////////////////////////////////////////////////////////////////////////////////
9497
9498MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9499{
9501 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9502}
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9506MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9507{
9508 return (MethodArgInfo_t*)
9510}
9511
9512////////////////////////////////////////////////////////////////////////////////
9513
9514bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9515{
9516 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9517 return info->IsValid();
9518}
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9522int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9523{
9524 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9525 return info->Next();
9526}
9527
9528////////////////////////////////////////////////////////////////////////////////
9529
9530Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9531{
9532 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9533 return info->Property();
9534}
9535
9536////////////////////////////////////////////////////////////////////////////////
9537
9538const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9539{
9540 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9541 return info->DefaultValue();
9542}
9543
9544////////////////////////////////////////////////////////////////////////////////
9545
9546const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9547{
9548 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9549 return info->Name();
9550}
9551
9552////////////////////////////////////////////////////////////////////////////////
9553
9554const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9555{
9556 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9557 return info->TypeName();
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561
9562std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9563{
9564 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9565 return info->Type()->NormalizedName(*fNormalizedCtxt);
9566}
9567
9568////////////////////////////////////////////////////////////////////////////////
9569
9570TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9571{
9572 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9573 return (TypeInfo_t*) info->Type();
9574}
9575
9576//______________________________________________________________________________
9577//
9578// TypeInfo interface
9579//
9580
9581////////////////////////////////////////////////////////////////////////////////
9582
9583void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9584{
9585 delete (TClingTypeInfo*) tinfo;
9586}
9587
9588////////////////////////////////////////////////////////////////////////////////
9589
9590TypeInfo_t* TCling::TypeInfo_Factory() const
9591{
9593 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9594}
9595
9596////////////////////////////////////////////////////////////////////////////////
9597
9598TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9599{
9601 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605
9606TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9607{
9608 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9609}
9610
9611////////////////////////////////////////////////////////////////////////////////
9612
9613void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9614{
9616 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9617 TClinginfo->Init(name);
9618}
9619
9620////////////////////////////////////////////////////////////////////////////////
9621
9622bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9623{
9624 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9625 return TClinginfo->IsValid();
9626}
9627
9628////////////////////////////////////////////////////////////////////////////////
9629
9630const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9631{
9632 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9633 return TClinginfo->Name();
9634}
9635
9636////////////////////////////////////////////////////////////////////////////////
9637
9638Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9639{
9640 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9641 return TClinginfo->Property();
9642}
9643
9644////////////////////////////////////////////////////////////////////////////////
9645
9646int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9647{
9648 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9649 return TClinginfo->RefType();
9650}
9651
9652////////////////////////////////////////////////////////////////////////////////
9653
9654int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9655{
9656 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9657 return TClinginfo->Size();
9658}
9659
9660////////////////////////////////////////////////////////////////////////////////
9661
9662const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9663{
9664 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9665 return TClinginfo->TrueName(*fNormalizedCtxt);
9666}
9667
9668////////////////////////////////////////////////////////////////////////////////
9669
9670void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9671{
9672 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9673 return TClinginfo->QualTypePtr();
9674}
9675
9676
9677//______________________________________________________________________________
9678//
9679// TypedefInfo interface
9680//
9681
9682////////////////////////////////////////////////////////////////////////////////
9683
9684void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9685{
9686 delete(TClingTypedefInfo*) tinfo;
9687}
9688
9689////////////////////////////////////////////////////////////////////////////////
9690
9691TypedefInfo_t* TCling::TypedefInfo_Factory() const
9692{
9694 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9695}
9696
9697////////////////////////////////////////////////////////////////////////////////
9698
9699TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9700{
9702 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9703}
9704
9705////////////////////////////////////////////////////////////////////////////////
9706
9707TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9708{
9709 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9710}
9711
9712////////////////////////////////////////////////////////////////////////////////
9713
9714void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9715 const char* name) const
9716{
9718 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9719 TClinginfo->Init(name);
9720}
9721
9722////////////////////////////////////////////////////////////////////////////////
9723
9724bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9725{
9726 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9727 return TClinginfo->IsValid();
9728}
9729
9730////////////////////////////////////////////////////////////////////////////////
9731
9732Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9733{
9734 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9735 return TClinginfo->Next();
9736}
9737
9738////////////////////////////////////////////////////////////////////////////////
9739
9740Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9741{
9742 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9743 return TClinginfo->Property();
9744}
9745
9746////////////////////////////////////////////////////////////////////////////////
9747
9748int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9749{
9750 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9751 return TClinginfo->Size();
9752}
9753
9754////////////////////////////////////////////////////////////////////////////////
9755
9756const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9757{
9758 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9759 return TClinginfo->TrueName(*fNormalizedCtxt);
9760}
9761
9762////////////////////////////////////////////////////////////////////////////////
9763
9764const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9765{
9766 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9767 return TClinginfo->Name();
9768}
9769
9770////////////////////////////////////////////////////////////////////////////////
9771
9772const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9773{
9774 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9775 return TClinginfo->Title();
9776}
9777
9778////////////////////////////////////////////////////////////////////////////////
9779
9780bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9781{
9782 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9783 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9784 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9785}
9786
9787////////////////////////////////////////////////////////////////////////////////
9788
9789bool TCling::IsIntegerType(const void * QualTypePtr) const
9790{
9791 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9792 return QT->hasIntegerRepresentation();
9793}
9794
9795////////////////////////////////////////////////////////////////////////////////
9796
9797bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9798{
9799 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9800 return QT->hasSignedIntegerRepresentation();
9801}
9802
9803////////////////////////////////////////////////////////////////////////////////
9804
9805bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9806{
9807 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9808 return QT->hasUnsignedIntegerRepresentation();
9809}
9810
9811////////////////////////////////////////////////////////////////////////////////
9812
9813bool TCling::IsFloatingType(const void * QualTypePtr) const
9814{
9815 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9816 return QT->hasFloatingRepresentation();
9817}
9818
9819////////////////////////////////////////////////////////////////////////////////
9820
9821bool TCling::IsPointerType(const void * QualTypePtr) const
9822{
9823 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9824 return QT->hasPointerRepresentation();
9825}
9826
9827////////////////////////////////////////////////////////////////////////////////
9828
9829bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9830{
9831 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9832 return QT->isVoidPointerType();
9833}
9834
9835////////////////////////////////////////////////////////////////////////////////
9836
9838{
9839 if (!fInitialMutex) {
9841 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9842 }
9843 fInitialMutex.fState = mtx->GetStateBefore();
9844 }
9845 // We will "forget" this lock once we backed out of all interpreter frames.
9846 // Here we are entering one, so ++.
9848}
9849
9850////////////////////////////////////////////////////////////////////////////////
9851
9853{
9854 if (!fInitialMutex)
9855 return;
9856 if (fInitialMutex.fRecurseCount == 0) {
9857 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9858 }
9859 else if (--fInitialMutex.fRecurseCount == 0) {
9860 // We have returned from all interpreter frames. Reset the initial lock state.
9861 fInitialMutex.fState.reset();
9862 }
9863}
9864
9865////////////////////////////////////////////////////////////////////////////////
9866/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9867
9869{
9870 if (gInterpreterMutex) {
9871 if (delta) {
9872 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9873 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9874 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9875 // Now that we have the lock, update the global
9876 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9877 std::swap(fInitialMutex, typedDelta->fInitialState);
9878 } else {
9879 // This case happens when EnableThreadSafety is first called from
9880 // the interpreter function we just handled.
9881 // Since thread safety was not enabled at the time we rewound, there was
9882 // no lock taken and even-though we should be locking the rest of this
9883 // interpreter handling/modifying code (since there might be threads in
9884 // flight), we can't because there would not be any lock guard to release the
9885 // locks
9887 Error("ApplyToInterpreterMutex",
9888 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9889 "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.");
9890 }
9891 }
9892}
9893
9894////////////////////////////////////////////////////////////////////////////////
9895/// Reset the interpreter lock to the state it had before interpreter-related
9896/// calls happened.
9897
9899{
9900 if (fInitialMutex) {
9901 // Need to start a new recurse count.
9902 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9903 std::swap(uniqueP->fInitialState, fInitialMutex);
9904 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9905 return uniqueP.release();
9906 }
9908 return nullptr;
9909}
free(fBuffer)
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:70
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:85
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:85
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
static bool IsFromRootCling()
Definition TClass.cxx:176
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:359
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:597
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1344
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7480
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:592
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:912
R__EXTERN int optind
Definition TCling.cxx:334
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:386
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:587
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:575
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:350
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:227
bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
Check if the class name is present in TClassTable.
Definition TCling.cxx:1021
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:4057
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:369
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:2007
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3273
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:651
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1116
bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname, std::string &result)
Try hard to avoid looking up in the Cling database as this could enduce an unwanted autoparsing.
Definition TCling.cxx:921
static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName=nullptr)
Checks if there is an ASTFile on disk for the given module M.
Definition TCling.cxx:1101
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:397
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:4099
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1730
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:646
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:224
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:717
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1115
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:254
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:611
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:582
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:622
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:4075
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:606
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:407
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:218
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:662
#define R__DLLEXPORT
Definition TCling.cxx:154
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:378
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:236
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:641
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1066
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1219
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8977
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:343
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:2507
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:7389
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:239
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:698
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:2032
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:626
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:7224
const char * fantomline
Definition TCling.cxx:859
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:601
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6543
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5723
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:221
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:618
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:1088
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:657
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:634
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7501
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:669
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
@ kIsNotReacheable
Definition TDictionary.h:87
#define gDirectory
Definition TDirectory.h:385
@ kEnvUser
Definition TEnv.h:26
@ kEnvGlobal
Definition TEnv.h:25
@ kEnvLocal
Definition TEnv.h:27
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:130
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
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:267
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:142
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
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
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:29
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3506
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2912
void RemoveStreamerInfo(Int_t slot)
Remove and delete the StreamerInfo in the given slot.
Definition TClass.cxx:7540
EState fState
!Current 'state' of the class (Emulated,Interpreted,Loaded)
Definition TClass.h:286
std::atomic< TList * > fBase
Definition TClass.h:204
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:578
Version_t fClassVersion
Definition TClass.h:225
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3861
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:5036
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:605
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3465
@ kLoading
Definition TClass.h:342
@ kUnloading
Definition TClass.h:342
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:6127
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5914
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5869
TObjArray * fStreamerInfo
Definition TClass.h:201
ClassInfo_t * GetClassInfo() const
Definition TClass.h:448
ClassInfo_t * fClassInfo
Definition TClass.h:226
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2923
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4278
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1813
@ kInterpreted
Definition TClass.h:129
@ kHasTClassInit
Definition TClass.h:130
@ kEmulated
Definition TClass.h:128
@ kForwardDeclared
Definition TClass.h:127
@ kNamespaceForMeta
Definition TClass.h:134
std::atomic< Bool_t > fCanLoadClassInfo
!Indicates whether the ClassInfo is supposed to be available.
Definition TClass.h:269
std::atomic< Bool_t > fHasRootPcmInfo
!Whether info was loaded from a root pcm.
Definition TClass.h:268
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3530
@ kIsTObject
Definition TClass.h:103
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:2999
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void SetArgs(const char *args)
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
bool IsAutoLoadingForJITSymbols() const
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingForJITSymbols(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
size_t GetAlignOf() const
Return the alignment of the class in bytes as reported by clang.
const char * TmpltName() 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
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
int Size() const
Return the size of the class in bytes as reported by clang.
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() 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.
const char * TypeName() const
const char * Name() const override
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() 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
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
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:1042
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1050
std::string fContent
Definition TCling.h:631
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6415
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9538
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8540
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9630
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9292
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4606
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:4037
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9724
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6476
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:8170
void SetGetline(const char *(*getlineFunc)(const char *prompt), void(*histaddFunc)(const char *line)) final
Set a getline function to call when input is needed.
Definition TCling.cxx:3800
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6785
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7685
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:140
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:8096
bool IsIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9789
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9351
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:8073
Bool_t fLockProcessLine
Definition TCling.h:129
int LoadFile(const char *path) const final
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7728
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3876
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8963
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:514
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:7120
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9333
void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4653
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8574
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8896
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7813
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:151
void CreateListOfDataMembers(TClass *cl) const final
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4700
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3921
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8566
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6994
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9646
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4577
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8453
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9380
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8710
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7743
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7517
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9430
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7944
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3712
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9301
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9053
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9590
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7782
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:7105
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const final
Definition TCling.cxx:9780
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7906
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7891
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3492
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9772
~TCling() final
Destroy the interpreter interface.
Definition TCling.cxx:1682
void CallFunc_SetFuncProto(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *proto, Longptr_t *Offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const final
Interface to cling function.
Definition TCling.cxx:8295
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5866
Int_t AutoParse(const char *cls) final
Parse the headers relative to the class Returns 1 in case of success, 0 in case of failure.
Definition TCling.cxx:6740
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1879
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4718
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7997
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2732
Bool_t fCxxModulesEnabled
Definition TCling.h:130
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8730
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6852
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:8147
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8131
std::set< std::string > fAutoLoadedLibraries
Definition TCling.h:125
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8196
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5674
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3316
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:4024
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:8162
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9868
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6808
Int_t GenerateDictionary(const char *classes, const char *includes="", const char *options=nullptr) final
Generate the dictionary for the C++ classes listed in the first argument (in a semi-colon separated l...
Definition TCling.cxx:4934
Bool_t ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const final
Return true if the entity pointed to by 'declid' is declared in the context described by 'info'.
Definition TCling.cxx:8369
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3282
Long_t GetExecByteCode() const final
This routines used to return the address of the internal wrapper function (of the interpreter) that w...
Definition TCling.cxx:7707
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8822
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8856
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3817
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:5739
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:155
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8590
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7834
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9514
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9654
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3935
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7715
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7870
void Print(Option_t *option="") const final
Print information about the interpreter.
Definition TCling.cxx:2742
std::set< size_t > fPayloads
Definition TCling.h:122
UInt_t FuncTempInfo_TemplateNargs(FuncTempInfo_t *) const final
Return the maximum number of template arguments of the function template described by ft_info.
Definition TCling.cxx:9087
DeclId_t GetFunctionWithPrototype(ClassInfo_t *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5366
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9691
TObjArray * fRootmapFiles
Definition TCling.h:128
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2537
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8638
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9554
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:656
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5614
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:148
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8880
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9764
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8703
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9342
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3704
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9064
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8872
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:9075
void AddIncludePath(const char *path) final
Add a directory to the list of directories in which the interpreter looks for include files.
Definition TCling.cxx:2774
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8525
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3835
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8920
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:5161
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8252
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8342
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9898
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9546
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3291
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9714
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8944
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8115
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3199
void SetAlloclockfunc(void(*)()) const final
[Place holder for Mutex Lock] Provide the interpreter with a way to acquire a lock used to protect cr...
Definition TCling.cxx:7764
Bool_t SetErrorMessages(Bool_t enable=kTRUE) final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7584
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:8154
void RegisterAutoLoadedLibrary(const char *libname) final
Register that a library was autoloaded either to provide a 'missing' symbol or to provide a class (se...
Definition TCling.cxx:3558
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9707
void GetFunctionOverloads(ClassInfo_t *cl, const char *funcname, std::vector< DeclId_t > &res) const final
Insert overloads of name in cl to res.
Definition TCling.cxx:5259
void UnRegisterTClassUpdate(const TClass *oldcl) final
If the dictionary is loaded, we can remove the class from the list (otherwise the class might be load...
Definition TCling.cxx:2477
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9562
DeclId_t GetEnum(TClass *cl, const char *name) const final
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition TCling.cxx:5043
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9530
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9748
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:8104
void GetInterpreterTypeName(const char *name, std::string &output, Bool_t full=kFALSE) final
The 'name' is known to the interpreter, this function returns the internal version of this name (usua...
Definition TCling.cxx:5411
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:646
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6974
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3667
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9732
void * GetInterfaceMethod(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return pointer to cling interface function for a method of a class with parameters params (params is ...
Definition TCling.cxx:5218
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9613
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7824
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8912
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8680
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8936
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5689
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:136
void ForgetMutexState() final
Definition TCling.cxx:9852
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9325
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8414
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9244
bool fIsShuttingDown
Definition TCling.h:189
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9483
bool IsSignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9797
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8837
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8445
TClass * GetClass(const std::type_info &typeinfo, Bool_t load) const final
Demangle the name (from the typeinfo) and then request the class via the usual name based interface (...
Definition TCling.cxx:6321
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6209
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8507
std::set< TClass * > & GetModTClasses()
Definition TCling.h:591
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8775
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE, ClassInfo_t **classInfo=nullptr) final
Checks if an entity with the specified name is defined in Cling.
Definition TCling.cxx:4366
TClingCallbacks * fClingCallbacks
Definition TCling.h:141
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8123
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8630
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8754
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:439
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5596
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7570
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7647
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7179
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:9108
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:487
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9662
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6227
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7917
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:176
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7217
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9522
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9837
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9638
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9371
UInt_t FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *) const final
Return the number of required template arguments of the function template described by ft_info.
Definition TCling.cxx:9098
std::vector< cling::Value > * fTemporaries
Definition TCling.h:135
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) final
Inject the module named "modulename" into cling; load all headers.
Definition TCling.cxx:2079
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6367
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9251
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4555
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7202
void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict) final
Register classes that already existed prior to their dictionary loading and that already had a ClassI...
Definition TCling.cxx:2468
bool IsVoidPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9829
TObjArray * GetRootMapFiles() const final
Definition TCling.h:226
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8864
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8533
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9317
bool IsFloatingType(const void *QualTypePtr) const final
Definition TCling.cxx:9813
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4709
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:6136
std::map< const cling::Transaction *, size_t > fTransactionHeadersMap
Definition TCling.h:120
void ReportDiagnosticsToErrorHandler(bool enable=true) final
Report diagnostics to the ROOT error handler (see TError.h).
Definition TCling.cxx:7843
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9360
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9570
Bool_t fHeaderParsingOnDemand
Definition TCling.h:183
std::hash< std::string > fStringHashFunction
Definition TCling.h:126
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:603
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5321
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8598
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7638
void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8999
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4734
const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7629
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9506
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8746
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7676
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3567
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9583
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9309
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:5152
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:127
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9419
void ProcessClassesToUpdate()
Definition TCling.cxx:2048
DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return pointer to cling DeclId for a method of a class with a certain prototype, i....
Definition TCling.cxx:5344
TString GetMangledName(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return the cling mangled name for a method of a class with parameters params (params is a string of a...
Definition TCling.cxx:5173
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9410
TString fRootmapLoadPath
Definition TCling.h:116
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE, ClassInfo_t *classInfo=nullptr) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4213
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8809
Bool_t Declare(const char *code) final
Declare code to the interpreter, without any of the interpreter actions that could trigger a re-inter...
Definition TCling.cxx:3236
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8791
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8260
int UnloadFile(const char *path) const final
Definition TCling.cxx:7876
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8080
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:9173
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8179
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8801
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:137
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8952
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4755
Bool_t fIsAutoParsingSuspended
Definition TCling.h:184
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1059
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:5083
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5444
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8558
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8646
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8767
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8268
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4689
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8654
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9212
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8688
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:4011
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1763
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6844
void ResetGlobals() final
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition TCling.cxx:3892
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7898
void ResetGlobalVar(void *obj) final
Reset the Cling 'user' global objects/variables state to the state saved by the last call to TCling::...
Definition TCling.cxx:3906
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7751
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3737
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:6148
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:4044
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8830
char fPrompt[64]
Definition TCling.h:110
const char * GetTopLevelMacroName() const final
Return the file name of the current un-included interpreted file.
Definition TCling.cxx:5627
void * fPrevLoadedDynLibInfo
Definition TCling.h:139
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition TCling.cxx:4727
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient) final
Visit all members over members, recursing over base classes.
Definition TCling.cxx:2796
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6289
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9285
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8188
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9490
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6968
DeclId_t GetFunction(ClassInfo_t *cl, const char *funcname) final
Return pointer to cling interface function for a method of a class with a certain name.
Definition TCling.cxx:5240
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8422
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:132
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8549
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:9044
bool IsUnsignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9805
DeclId_t GetFunctionTemplate(ClassInfo_t *cl, const char *funcname) final
Return pointer to cling interface function for a method of a class with a certain name.
Definition TCling.cxx:5388
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3950
const char * GetClassSharedLibs(const char *cls, bool skipCore=true) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7323
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8888
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:8139
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9260
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8904
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3191
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:657
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2526
void SetAllocunlockfunc(void(*)()) const final
[Place holder for Mutex Unlock] Provide the interpreter with a way to release a lock used to protect ...
Definition TCling.cxx:7774
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
bool IsValid() const final
Check if constructor exited correctly, ie the instance is in a valid state.
Definition TCling.cxx:3182
void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2442
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9684
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3860
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9756
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7795
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8662
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:6592
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9389
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8204
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7598
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:7078
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6910
void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1700
int ClassInfo_GetMethodNArg(ClassInfo_t *info, const char *method, const char *proto, Bool_t objectIsConst=false, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8483
DeclId_t GetDataMember(ClassInfo_t *cl, const char *name) const final
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition TCling.cxx:4982
void * fAutoLoadCallBack
Definition TCling.h:149
void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const final
Return the name of this function template.
Definition TCling.cxx:9199
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:133
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9622
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1974
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9398
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8672
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4765
ULong64_t fTransactionCount
Definition TCling.h:150
std::set< std::string > fAutoParseClasses
Definition TCling.h:124
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8491
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3265
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9606
size_t ClassInfo_AlignOf(ClassInfo_t *info) const final
Definition TCling.cxx:8358
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8499
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8437
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition TCling.h:119
const char * DataMemberInfo_TypeTrueName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8928
void ShutDown() final
Definition TCling.cxx:1721
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:4051
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9670
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9740
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1744
Longptr_t ProcessLineSynch(const char *line, EErrorCode *error=nullptr) final
Let cling process a command line synchronously, i.e we are waiting it will be finished.
Definition TCling.cxx:3721
TString GetMangledNameWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return the cling mangled name for a method of a class with a certain prototype, i....
Definition TCling.cxx:5200
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6983
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5952
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8783
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7209
bool IsPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9821
Collection abstract base class.
Definition TCollection.h:65
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
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:181
@ kNone
Definition TEnum.h:55
@ kAutoload
Definition TEnum.h:59
Definition TEnv.h:41
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:79
THashList * GetTable() const
Definition TEnv.h:96
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:809
virtual void SetRcName(const char *name)
Definition TEnv.h:101
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:612
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:752
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:567
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
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) override
Remove object from the list.
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
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 void RegisterAutoLoadedLibrary(const char *libname)=0
virtual Bool_t Declare(const char *code)=0
virtual const char * GetClassSharedLibs(const char *cls, bool skipCore=true)=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...
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...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A doubly linked list.
Definition TList.h:38
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:27
Abstract base class for accessing the data-members of a class.
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
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TNamed()
Definition TNamed.h:38
An array of TObjects.
Definition TObjArray.h:31
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:160
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:424
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1124
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:506
virtual TClass * IsA() const
Definition TObject.h:248
void MakeZombie()
Definition TObject.h:55
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:81
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1070
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:3362
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2932
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:3128
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3396
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:3138
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation.
Definition TROOT.cxx:3223
Sequenceable collection abstract base class.
Int_t LastIndex() const
Describes a persistent version of a class.
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1242
const char * Data() const
Definition TString.h:385
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
Bool_t IsNull() const
Definition TString.h:423
TString & Append(const char *cs)
Definition TString.h:582
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:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1296
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:860
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:851
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1687
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:4063
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4350
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1560
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1879
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:1420
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1097
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:1318
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:868
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2516
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:949
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1817
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2056
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:2901
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:886
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1570
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1671
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:902
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1047
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:748
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2042
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:53
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TLine * line
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
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...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a valid name of the C++ symbol/type (pass as 'input') that can be u...
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...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
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.
R__EXTERN TVirtualRWMutex * gCoreMutex
@ kWarning
Warnings about likely unexpected behavior.
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:235
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:230
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:231
std::string InsertStd(const char *tname)
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:255
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:83
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:159
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:164
A read-only memory range which we do not control.
Definition TMemFile.h:33
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4