Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include "llvm/IR/GlobalValue.h"
119#include "llvm/IR/Module.h"
120
121#include "llvm/Support/DynamicLibrary.h"
122#include "llvm/Support/raw_ostream.h"
123#include "llvm/Support/Path.h"
124#include "llvm/Support/Process.h"
125#include "llvm/Object/ELFObjectFile.h"
126#include "llvm/Object/ObjectFile.h"
127#include "llvm/Object/SymbolicFile.h"
128#include "llvm/Support/FileSystem.h"
129
130#include <algorithm>
131#include <iostream>
132#include <cassert>
133#include <map>
134#include <set>
135#include <stdexcept>
136#include <stdint.h>
137#include <fstream>
138#include <sstream>
139#include <string>
140#include <tuple>
141#include <typeinfo>
142#include <unordered_map>
143#include <unordered_set>
144#include <utility>
145#include <vector>
146#include <functional>
147#include <optional>
148
149#ifndef R__WIN32
150#include <cxxabi.h>
151#define R__DLLEXPORT __attribute__ ((visibility ("default")))
152#include <sys/stat.h>
153#endif
154#include <limits.h>
155#include <stdio.h>
156
157#ifdef __APPLE__
158#include <dlfcn.h>
159#include <mach-o/dyld.h>
160#include <mach-o/loader.h>
161#endif // __APPLE__
162
163#ifdef R__UNIX
164#include <dlfcn.h>
165#endif
166
167#if defined(R__LINUX) || defined(R__FBSD)
168# ifndef _GNU_SOURCE
169# define _GNU_SOURCE
170# endif
171# include <link.h> // dl_iterate_phdr()
172#endif
173
174#if defined(__CYGWIN__)
175#include <sys/cygwin.h>
176#define HMODULE void *
177extern "C" {
178 __declspec(dllimport) void * __stdcall GetCurrentProcess();
179 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
180 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
181}
182#endif
183
184// Fragment copied from LLVM's raw_ostream.cpp
185#if defined(_MSC_VER)
186#ifndef STDIN_FILENO
187# define STDIN_FILENO 0
188#endif
189#ifndef STDOUT_FILENO
190# define STDOUT_FILENO 1
191#endif
192#ifndef STDERR_FILENO
193# define STDERR_FILENO 2
194#endif
195#ifndef R__WIN32
196//#if defined(HAVE_UNISTD_H)
197# include <unistd.h>
198//#endif
199#else
200#include "Windows4Root.h"
201#include <Psapi.h>
202#include <direct.h>
203#undef GetModuleFileName
204#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
205#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
206#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
207#define dlclose(library) ::FreeLibrary((HMODULE)library)
208#define R__DLLEXPORT __declspec(dllexport)
209#endif
210#endif
211
212//______________________________________________________________________________
213// These functions are helpers for debugging issues with non-LLVMDEV builds.
214//
215R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
216 return D->getDeclContext();
217}
218R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
219 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
220}
221R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::RecordDecl>(DC);
223}
224R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
225 return DC->dumpDeclContext();
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
228 return D->dump();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
231 return FD->dump();
232}
234 return ((clang::Decl*)D)->dump();
235}
237 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
238 std::string name;
239 {
240 llvm::raw_string_ostream OS(name);
241 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
242 true /*Qualified*/);
243 }
244 printf("%s\n", name.c_str());
245 }
246}
247//______________________________________________________________________________
248// These functions are helpers for testing issues directly rather than
249// relying on side effects.
250// This is used for the test for ROOT-7462/ROOT-6070
252 return D->isInvalidDecl();
253}
256 assert(info && info->IsValid());
257 return info->GetDecl()->isInvalidDecl();
258}
259
260using std::string, std::vector;
261using namespace clang;
262using namespace ROOT;
263
264namespace {
265 static const std::string gInterpreterClassDef = R"ICF(
266#undef ClassDef
267#define ClassDef(name, id) \
268_ClassDefInterp_(name,id,virtual,) \
269static int DeclFileLine() { return __LINE__; }
270#undef ClassDefNV
271#define ClassDefNV(name, id) \
272_ClassDefInterp_(name,id,,) \
273static int DeclFileLine() { return __LINE__; }
274#undef ClassDefOverride
275#define ClassDefOverride(name, id) \
276_ClassDefInterp_(name,id,,override) \
277static int DeclFileLine() { return __LINE__; }
278)ICF";
279
280 static const std::string gNonInterpreterClassDef = R"ICF(
281#define __ROOTCLING__ 1
282#undef ClassDef
283#define ClassDef(name,id) \
284_ClassDefOutline_(name,id,virtual,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefNV
287#define ClassDefNV(name, id)\
288_ClassDefOutline_(name,id,,)\
289static int DeclFileLine() { return __LINE__; }
290#undef ClassDefOverride
291#define ClassDefOverride(name, id)\
292_ClassDefOutline_(name,id,,override)\
293static int DeclFileLine() { return __LINE__; }
294)ICF";
295
296// The macros below use ::Error, so let's ensure it is included
297 static const std::string gClassDefInterpMacro = R"ICF(
298#include "TError.h"
299
300#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
301private: \
302public: \
303 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
304 static const char *Class_Name() { return #name; } \
305 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
306 static Version_t Class_Version() { return id; } \
307 static TClass *Dictionary() { return 0; } \
308 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
309 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
310 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
311 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
312 static const char *DeclFileName() { return __FILE__; } \
313 static int ImplFileLine() { return 0; } \
314 static const char *ImplFileName() { return __FILE__; }
315)ICF";
316}
318
319// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
320// ROOT (which uses rtti)
321
322////////////////////////////////////////////////////////////////////////////////
323/// Print a StackTrace!
324
325extern "C"
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load a library.
332
333extern "C" int TCling__LoadLibrary(const char *library)
334{
335 return gSystem->Load(library, "", false);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
340
341extern "C" void TCling__RestoreInterpreterMutex(void *delta)
342{
343 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
348/// which is extracted by error messages we get from callback from cling. Return true
349/// when the missing library was autoloaded.
350
351extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
352{
353 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Reset the interpreter lock to the state it had before interpreter-related
358/// calls happened.
359
361{
362 return ((TCling*)gCling)->RewindInterpreterMutex();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Lock the interpreter.
367
369{
370 if (gInterpreterMutex) {
372 }
373 return nullptr;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Unlock the interpreter.
378
380{
381 if (gInterpreterMutex) {
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
388
389static void TCling__UpdateClassInfo(const NamedDecl* TD)
390{
391 static Bool_t entered = kFALSE;
392 static vector<const NamedDecl*> updateList;
393 Bool_t topLevel;
394
395 if (entered) topLevel = kFALSE;
396 else {
397 entered = kTRUE;
398 topLevel = kTRUE;
399 }
400 if (topLevel) {
401 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
402 } else {
403 // If we are called indirectly from within another call to
404 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
405 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
406 // This allows for the dictionary to be fully populated when we actually
407 // update the TClass object. The updating of the TClass sometimes
408 // (STL containers and when there is an emulated class) forces the building
409 // of the TClass object's real data (which needs the dictionary info).
410 updateList.push_back(TD);
411 }
412 if (topLevel) {
413 while (!updateList.empty()) {
414 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
415 updateList.pop_back();
416 }
417 entered = kFALSE;
418 }
419}
420
421void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
422 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
423 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
424 // Add the constants to the enum type.
425 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
426 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
427 // Get name of the enum type.
428 std::string constbuf;
429 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
430 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
431 llvm::raw_string_ostream stream(constbuf);
432 // Don't trigger fopen of the source file to count lines:
433 Policy.AnonymousTagLocations = false;
434 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
435 }
436 const char* constantName = constbuf.c_str();
437
438 // Get value of the constant.
440 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
441 if (valAPSInt.isSigned()) {
442 value = valAPSInt.getSExtValue();
443 } else {
444 value = valAPSInt.getZExtValue();
445 }
446
447 // Create the TEnumConstant or update it if existing
448 TEnumConstant* enumConstant = nullptr;
449 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
450 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
451 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
452 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
453 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
454 } else {
455 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
456 }
457
458 // Add the global constants to the list of Globals.
459 if (!cl) {
460 TCollection* globals = gROOT->GetListOfGlobals(false);
461 if (!globals->FindObject(constantName)) {
462 globals->Add(enumConstant);
463 }
464 }
465 }
466 }
467}
468
469TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
470{
471 // Handle new enum declaration for either global and nested enums.
472
473 // Create the enum type.
474 TEnum* enumType = nullptr;
475 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
476 std::string buf;
477 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
478 // Get name of the enum type.
479 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
480 llvm::raw_string_ostream stream(buf);
481 // Don't trigger fopen of the source file to count lines:
482 Policy.AnonymousTagLocations = false;
483 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
484 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
485 }
486 if (buf.empty()) {
487 return nullptr;
488 }
489 const char* name = buf.c_str();
490 enumType = new TEnum(name, VD, cl);
491 UpdateEnumConstants(enumType, cl);
492
493 return enumType;
494}
495
496void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
497 // Handle new declaration.
498 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
499
500 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
501
502 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
503 && !dyn_cast<clang::RecordDecl>(D)) return;
504
505 if (isa<clang::FunctionDecl>(D->getDeclContext())
506 || isa<clang::TagDecl>(D->getDeclContext()))
507 return;
508
509 // Don't list templates.
510 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
511 if (RD->getDescribedClassTemplate())
512 return;
513 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
514 if (FD->getDescribedFunctionTemplate())
515 return;
516 }
517
518 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
519 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
521 }
522 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
523
524 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
525 // Mostly just for EnumDecl (the other TagDecl are handled
526 // by the 'RecordDecl' if statement.
528 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
530 }
531
532 // We care about declarations on the global scope.
533 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
534 return;
535
536 // Enums are lazyly created, thus we don not need to handle them here.
537 if (isa<EnumDecl>(ND))
538 return;
539
540 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
541 // scope.
542 if (!(isa<VarDecl>(ND)))
543 return;
544
545 // Skip if already in the list.
546 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
547 return;
548
549 // Put the global constants and global enums in the corresponding lists.
550 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
552 cast<ValueDecl>(ND), nullptr)));
553 }
554}
555
556extern "C"
558{
559 // We are sure in this context of the type of the interpreter
560 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
561}
562
563extern "C"
564void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
565 ((TCling*)gCling)->UpdateListsOnCommitted(T);
566}
567
568extern "C"
569void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
570 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
571}
572
573extern "C"
574void TCling__InvalidateGlobal(const clang::Decl *D) {
575 ((TCling*)gCling)->InvalidateGlobal(D);
576}
577
578extern "C"
579void TCling__TransactionRollback(const cling::Transaction &T) {
580 ((TCling*)gCling)->TransactionRollback(T);
581}
582
583extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
584 const char* canonicalName) {
585 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
586}
587
588extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
589{
590 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
591}
592
593extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
594 const char* canonicalName) {
595 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
596}
597
598
599extern "C"
600TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
601 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
602}
603
604extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
605 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
606}
607
608extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
609 const char* argv[])
610{
611 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
612
613 return tcling;
614}
615
617{
618 delete interp;
619}
620
621// Load library containing specified class. Returns 0 in case of error
622// and 1 in case if success.
623extern "C" int TCling__AutoLoadCallback(const char* className)
624{
625 return ((TCling*)gCling)->AutoLoad(className);
626}
627
628extern "C" int TCling__AutoParseCallback(const char* className)
629{
630 return ((TCling*)gCling)->AutoParse(className);
631}
632
633extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
634{
635 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
636}
637
638// Returns 0 for failure 1 for success
639extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
640{
641 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
642}
643
644extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
645{
646 string file(fileName);
647 string opt(options);
648 return gSystem->CompileMacro(file.c_str(), opt.c_str());
649}
650
651extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
652 string &args, string &io, string &fname)
653{
654 string file(fileName);
655 TString f, amode, arguments, aclicio;
656 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
657 mode = amode.Data(); args = arguments.Data();
658 io = aclicio.Data(); fname = f.Data();
659}
660
661//______________________________________________________________________________
662//
663//
664//
665
666#ifdef R__WIN32
667extern "C" {
668 char *__unDName(char *demangled, const char *mangled, int out_len,
669 void * (* pAlloc )(size_t), void (* pFree )(void *),
670 unsigned short int flags);
671}
672#endif
673
674////////////////////////////////////////////////////////////////////////////////
675/// Find a template decl within N nested namespaces, 0<=N<inf
676/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
677/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
678/// Returns nullptr in case of error
679
680static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
681{
682 using namespace clang;
683 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
684 return FindTemplateInNamespace(*nsd->decls_begin());
685 }
686
687 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
688 return ctd;
689 }
690
691 return nullptr; // something went wrong.
692}
693
694//______________________________________________________________________________
695//
696//
697//
698
699int TCling_GenerateDictionary(const std::vector<std::string> &classes,
700 const std::vector<std::string> &headers,
701 const std::vector<std::string> &fwdDecls,
702 const std::vector<std::string> &unknown)
703{
704 //This function automatically creates the "LinkDef.h" file for templated
705 //classes then executes CompileMacro on it.
706 //The name of the file depends on the class name, and it's not generated again
707 //if the file exist.
708 if (classes.empty()) {
709 return 0;
710 }
711 // Use the name of the first class as the main name.
712 const std::string& className = classes[0];
713 //(0) prepare file name
714 TString fileName = "AutoDict_";
715 std::string::const_iterator sIt;
716 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
717 if (*sIt == '<' || *sIt == '>' ||
718 *sIt == ' ' || *sIt == '*' ||
719 *sIt == ',' || *sIt == '&' ||
720 *sIt == ':') {
721 fileName += '_';
722 }
723 else {
724 fileName += *sIt;
725 }
726 }
727 if (classes.size() > 1) {
728 Int_t chk = 0;
729 std::vector<std::string>::const_iterator it = classes.begin();
730 while ((++it) != classes.end()) {
731 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
732 chk = chk * 3 + it->at(cursor);
733 }
734 }
735 fileName += TString::Format("_%u", chk);
736 }
737 fileName += ".cxx";
738 if (gSystem->AccessPathName(fileName) != 0) {
739 //file does not exist
740 //(1) prepare file data
741 // If STL, also request iterators' operators.
742 // vector is special: we need to check whether
743 // vector::iterator is a typedef to pointer or a
744 // class.
745 static const std::set<std::string> sSTLTypes {
746 "vector","list","forward_list","deque","map","unordered_map","multimap",
747 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
748 "queue","priority_queue","stack","iterator"};
749 std::vector<std::string>::const_iterator it;
750 std::string fileContent("");
751 for (it = headers.begin(); it != headers.end(); ++it) {
752 fileContent += "#include \"" + *it + "\"\n";
753 }
754 for (it = unknown.begin(); it != unknown.end(); ++it) {
755 TClass* cl = TClass::GetClass(it->c_str());
756 if (cl && cl->GetDeclFileName()) {
757 TString header = gSystem->BaseName(cl->GetDeclFileName());
759 TString dirbase(gSystem->BaseName(dir));
760 while (dirbase.Length() && dirbase != "."
761 && dirbase != "include" && dirbase != "inc"
762 && dirbase != "prec_stl") {
763 gSystem->PrependPathName(dirbase, header);
764 dir = gSystem->GetDirName(dir);
765 }
766 fileContent += TString("#include \"") + header + "\"\n";
767 }
768 }
769 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
770 fileContent += "class " + *it + ";\n";
771 }
772 fileContent += "#ifdef __CLING__ \n";
773 fileContent += "#pragma link C++ nestedclasses;\n";
774 fileContent += "#pragma link C++ nestedtypedefs;\n";
775 for (it = classes.begin(); it != classes.end(); ++it) {
776 std::string n(*it);
777 size_t posTemplate = n.find('<');
778 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
779 if (posTemplate != std::string::npos) {
780 n.erase(posTemplate, std::string::npos);
781 if (n.compare(0, 5, "std::") == 0) {
782 n.erase(0, 5);
783 }
784 iSTLType = sSTLTypes.find(n);
785 }
786 fileContent += "#pragma link C++ class ";
787 fileContent += *it + "+;\n" ;
788 fileContent += "#pragma link C++ class ";
789 if (iSTLType != sSTLTypes.end()) {
790 // STL class; we cannot (and don't need to) store iterators;
791 // their shadow and the compiler's version don't agree. So
792 // don't ask for the '+'
793 fileContent += *it + "::*;\n" ;
794 }
795 else {
796 // Not an STL class; we need to allow the I/O of contained
797 // classes (now that we have a dictionary for them).
798 fileContent += *it + "::*+;\n" ;
799 }
800 }
801 fileContent += "#endif\n";
802 //end(1)
803 //(2) prepare the file
804 FILE* filePointer;
805 filePointer = fopen(fileName, "w");
806 if (filePointer == nullptr) {
807 //can't open a file
808 return 1;
809 }
810 //end(2)
811 //write data into the file
812 fprintf(filePointer, "%s", fileContent.c_str());
813 fclose(filePointer);
814 }
815 //(3) checking if we can compile a macro, if not then cleaning
816 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
817 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
818 Int_t ret = gSystem->CompileMacro(fileName, "k");
819 gErrorIgnoreLevel = oldErrorIgnoreLevel;
820 if (ret == 0) { //can't compile a macro
821 return 2;
822 }
823 //end(3)
824 return 0;
825}
826
827int TCling_GenerateDictionary(const std::string& className,
828 const std::vector<std::string> &headers,
829 const std::vector<std::string> &fwdDecls,
830 const std::vector<std::string> &unknown)
831{
832 //This function automatically creates the "LinkDef.h" file for templated
833 //classes then executes CompileMacro on it.
834 //The name of the file depends on the class name, and it's not generated again
835 //if the file exist.
836 std::vector<std::string> classes;
837 classes.push_back(className);
838 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
839}
840
841//______________________________________________________________________________
842//
843//
844//
845
846// It is a "fantom" method to synchronize user keyboard input
847// and ROOT prompt line (for WIN32)
848const char* fantomline = "TRint::EndOfLineAction();";
849
850//______________________________________________________________________________
851//
852//
853//
854
855void* TCling::fgSetOfSpecials = nullptr;
856
857//______________________________________________________________________________
858//
859// llvm error handler through exceptions; see also cling/UserInterface
860//
861namespace {
862 // Handle fatal llvm errors by throwing an exception.
863 // Yes, throwing exceptions in error handlers is bad.
864 // Doing nothing is pretty terrible, too.
865 void exceptionErrorHandler(void * /*user_data*/,
866 const char *reason,
867 bool /*gen_crash_diag*/) {
868 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
869 }
870}
871
872//______________________________________________________________________________
873//
874//
875//
876
877////////////////////////////////////////////////////////////////////////////////
878
879namespace{
880 // An instance of this class causes the diagnostics of clang to be suppressed
881 // during its lifetime
882 class clangDiagSuppr {
883 public:
884 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
885 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
886 fDiagEngine.setIgnoreAllWarnings(true);
887 }
888
889 ~clangDiagSuppr() {
890 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
891 }
892 private:
893 clang::DiagnosticsEngine& fDiagEngine;
894 bool fOldDiagValue;
895 };
896
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Allow calling autoparsing from TMetaUtils
902{
903 return gCling->AutoParse(cname);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Try hard to avoid looking up in the Cling database as this could enduce
908/// an unwanted autoparsing.
909
910bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
911 std::string &result)
912{
913 result.clear();
914
915 unsigned long offset = 0;
916 if (strncmp(tname.c_str(), "const ", 6) == 0) {
917 offset = 6;
918 }
919 unsigned long end = tname.length();
920 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
921 if ( tname[end-1]==']' ) {
922 --end;
923 while ( end && tname[end-1]!='[' ) --end;
924 }
925 --end;
926 }
927 std::string innerbuf;
928 const char *inner;
929 if (end != tname.length()) {
930 innerbuf = tname.substr(offset,end-offset);
931 inner = innerbuf.c_str();
932 } else {
933 inner = tname.c_str()+offset;
934 }
935
936 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
937 if (gROOT->GetListOfClasses()->FindObject(inner)
938 || TClassTable::Check(inner,result) ) {
939 // This is a known class.
940 return true;
941 }
942
943 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
944 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
945 if (type) {
946 // This is a raw type and an already loaded typedef.
947 const char *newname = type->GetFullTypeName();
948 if (type->GetType() == kLong64_t) {
949 newname = "Long64_t";
950 } else if (type->GetType() == kULong64_t) {
951 newname = "ULong64_t";
952 }
953 if (strcmp(inner,newname) == 0) {
954 return true;
955 }
956 if (offset) result = "const ";
957 result += newname;
958 if ( end != tname.length() ) {
959 result += tname.substr(end,tname.length()-end);
960 }
961 if (result == tname) result.clear();
962 return true;
963 }
964
965 // Check if the name is an enumerator
966 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
967 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
968 {
969 // We have a scope
970 // All of this C gymnastic is to avoid allocations on the heap
971 const auto enName = lastPos;
972 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
973 char *scopeName = new char[scopeNameSize + 1];
974 strncpy(scopeName, inner, scopeNameSize);
975 scopeName[scopeNameSize] = '\0';
976 // Check if the scope is in the list of classes
977 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
978 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
979 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
980 }
981 // It may still be in one of the loaded protoclasses
982 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
983 auto listOfEnums = scope->GetListOfEnums();
984 if (listOfEnums) { // it could be null: no enumerators in the protoclass
985 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
986 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
987 }
988 }
989 delete [] scopeName;
990 } else
991 {
992 // We don't have any scope: this could only be a global enum
993 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
994 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
995 }
996
997 if (gCling->GetClassSharedLibs(inner))
998 {
999 // This is a class name.
1000 return true;
1001 }
1002
1003 return false;
1004}
1005
1006////////////////////////////////////////////////////////////////////////////////
1007
1009{
1010 fContent.reserve(size);
1011}
1012
1013////////////////////////////////////////////////////////////////////////////////
1014
1016{
1017 return fContent.c_str();
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Append string to the storage if not added already.
1022
1023inline bool TCling::TUniqueString::Append(const std::string& str)
1024{
1025 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1026 if (notPresent){
1027 fContent+=str;
1028 }
1029 return notPresent;
1030}
1031
1032std::string TCling::ToString(const char* type, void* obj)
1033{
1034 return fInterpreter->toString(type, obj);
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038///\returns true if the module was loaded.
1039static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1040{
1041 // When starting up ROOT, cling would load all modulemap files on the include
1042 // paths. However, in a ROOT session, it is very common to run aclic which
1043 // will invoke rootcling and possibly produce a modulemap and a module in
1044 // the current folder.
1045 //
1046 // Before failing, try loading the modulemap in the current folder and try
1047 // loading the requested module from it.
1048 std::string currentDir = gSystem->WorkingDirectory();
1049 assert(!currentDir.empty());
1051 if (gDebug > 2)
1052 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1053 ModuleName.c_str());
1054
1055 return interp.loadModule(ModuleName, /*Complain=*/true);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Loads the C++ modules that we require to run any ROOT program. This is just
1060/// supposed to make a C++ module from a modulemap available to the interpreter.
1061static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1062{
1063 for (const auto &modName : modules)
1064 LoadModule(modName, interp);
1065}
1066
1067static bool IsFromRootCling() {
1068 // rootcling also uses TCling for generating the dictionary ROOT files.
1069 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1070 return foundSymbol;
1071}
1072
1073/// Checks if there is an ASTFile on disk for the given module \c M.
1074static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1075{
1076 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1077
1078 std::string ModuleFileName;
1079 if (!HSOpts.PrebuiltModulePaths.empty())
1080 // Load the module from *only* in the prebuilt module path.
1081 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1082 if (FullFileName)
1083 *FullFileName = ModuleFileName;
1084
1085 return !ModuleFileName.empty();
1086}
1087
1088static bool HaveFullGlobalModuleIndex = false;
1089static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1090{
1091 CompilerInstance &CI = *interp.getCI();
1092 Preprocessor &PP = CI.getPreprocessor();
1093 auto ModuleManager = CI.getASTReader();
1094 assert(ModuleManager);
1095 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1096 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1097 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1098 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1099 if (ModuleIndexPath.empty())
1100 return nullptr;
1101 // Get an existing global index. This loads it if not already loaded.
1102 ModuleManager->resetForReload();
1103 ModuleManager->loadGlobalIndex();
1104 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1105
1106 // For finding modules needing to be imported for fixit messages,
1107 // we need to make the global index cover all modules, so we do that here.
1108 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1109 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1110 bool RecreateIndex = false;
1111 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1112 Module *TheModule = I->second;
1113 // We want the index only of the prebuilt modules.
1114 if (!HasASTFileOnDisk(TheModule, PP))
1115 continue;
1116 LoadModule(TheModule->Name, interp);
1117 RecreateIndex = true;
1118 }
1119 if (RecreateIndex) {
1120 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1121 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1122
1123 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1124 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1125 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1126 TraverseDecl(TU);
1127 }
1128 bool VisitNamedDecl(NamedDecl *ND) {
1129 if (!ND->isFromASTFile())
1130 return true;
1131 if (!ND->getIdentifier())
1132 return true;
1133
1134 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1135 return true;
1136
1137 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1138 if (TD->isCompleteDefinition())
1139 Register(TD);
1140 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1141 Register(NSD, /*AddSingleEntry=*/ false);
1142 }
1143 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1144 Register(TND);
1145 // FIXME: Add the rest...
1146 return true; // continue decending
1147 }
1148 private:
1149 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1150 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1151 assert(ND->isFromASTFile());
1152 // FIXME: All decls should have an owning module once rootcling
1153 // updates its generated decls from within the LookupHelper & co.
1154 if (!ND->hasOwningModule()) {
1155#ifndef NDEBUG
1156 SourceManager &SM = ND->getASTContext().getSourceManager();
1157 SourceLocation Loc = ND->getLocation();
1158 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1159 (void)FE;
1160 assert(FE->getName().contains("input_line_"));
1161#endif
1162 return;
1163 }
1164
1165 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1166 assert(OwningModule);
1167 assert(!ND->getName().empty() && "Empty name");
1168 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1169 return;
1170 // FIXME: The FileEntry in not stable to serialize.
1171 // FIXME: We might end up with many times with the same module.
1172 // FIXME: We might end up two modules containing a definition.
1173 // FIXME: What do we do if no definition is found.
1174 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1175 }
1176 };
1177 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1178
1179 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1180 CI.getPCHContainerReader(),
1181 ModuleIndexPath,
1182 &IDs));
1183 ModuleManager->resetForReload();
1184 ModuleManager->loadGlobalIndex();
1185 GlobalIndex = ModuleManager->getGlobalIndex();
1186 }
1188 }
1189 return GlobalIndex;
1190}
1191
1192static void RegisterCxxModules(cling::Interpreter &clingInterp)
1193{
1194 if (!clingInterp.getCI()->getLangOpts().Modules)
1195 return;
1196
1197 // Loading of a module might deserialize.
1198 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1199
1200 // Setup core C++ modules if we have any to setup.
1201
1202 // Load libc and stl first.
1203 // Load vcruntime module for windows
1204#ifdef R__WIN32
1205 LoadModule("vcruntime", clingInterp);
1206 LoadModule("services", clingInterp);
1207#endif
1208
1209#ifdef R__MACOSX
1210 LoadModule("Darwin", clingInterp);
1211#else
1212 LoadModule("libc", clingInterp);
1213#endif
1214 LoadModule("std", clingInterp);
1215
1216 LoadModule("_Builtin_intrinsics", clingInterp);
1217
1218 // Load core modules
1219 // This should be vector in order to be able to pass it to LoadModules
1220 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1221 "ROOT_Config",
1222 "ROOT_Rtypes",
1223 "ROOT_Foundation_Stage1_NoRTTI",
1224 "Core",
1225 "Rint",
1226 "RIO"};
1227
1228 LoadModules(CoreModules, clingInterp);
1229
1230 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1231 if (!IsFromRootCling()) {
1232 std::vector<std::string> CommonModules = {"MathCore"};
1233 LoadModules(CommonModules, clingInterp);
1234
1235 // These modules should not be preloaded but they fix issues.
1236 // FIXME: Hist is not a core module but is very entangled to MathCore and
1237 // causes issues.
1238 std::vector<std::string> FIXMEModules = {"Hist"};
1239 clang::CompilerInstance &CI = *clingInterp.getCI();
1240 clang::Preprocessor &PP = CI.getPreprocessor();
1241 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1242 if (MMap.findModule("RInterface"))
1243 FIXMEModules.push_back("RInterface");
1244
1245 LoadModules(FIXMEModules, clingInterp);
1246
1247 GlobalModuleIndex *GlobalIndex = nullptr;
1248 loadGlobalModuleIndex(clingInterp);
1249 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1250 // We should investigate how to suppress it completely.
1251 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1252
1253 llvm::StringSet<> KnownModuleFileNames;
1254 if (GlobalIndex)
1255 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1256
1257 std::vector<std::string> PendingModules;
1258 PendingModules.reserve(256);
1259 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1260 clang::Module *M = I->second;
1261 assert(M);
1262
1263 // We want to load only already created modules.
1264 std::string FullASTFilePath;
1265 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1266 continue;
1267
1268 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1269 continue;
1270
1271 if (M->IsUnimportable)
1272 continue;
1273
1274 if (GlobalIndex)
1275 LoadModule(M->Name, clingInterp);
1276 else {
1277 // FIXME: We may be able to remove those checks as cling::loadModule
1278 // checks if a module was alredy loaded.
1279 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1280 continue; // This is a core module which was already loaded.
1281
1282 // Load system modules now and delay the other modules after we have
1283 // loaded all system ones.
1284 if (M->IsSystem)
1285 LoadModule(M->Name, clingInterp);
1286 else
1287 PendingModules.push_back(M->Name);
1288 }
1289 }
1290 LoadModules(PendingModules, clingInterp);
1291 }
1292
1293 // Check that the gROOT macro was exported by any core module.
1294 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1295
1296 // `ERROR` and `PI` are from loading R related modules, which conflict with
1297 // user's code.
1298 clingInterp.declare(R"CODE(
1299#ifdef PI
1300# undef PI
1301#endif
1302#ifdef ERROR
1303# undef ERROR
1304#endif
1305 )CODE");
1306}
1307
1308static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1309{
1310 std::string PreIncludes;
1311 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1312
1313 // For the list to also include string, we have to include it now.
1314 // rootcling does parts already if needed, e.g. genreflex does not want using
1315 // namespace std.
1316 if (IsFromRootCling()) {
1317 PreIncludes += "#include \"RtypesCore.h\"\n";
1318 } else {
1319 if (!hasCxxModules)
1320 PreIncludes += "#include \"Rtypes.h\"\n";
1321
1322 PreIncludes += gClassDefInterpMacro + "\n"
1323 + gInterpreterClassDef + "\n"
1324 "#undef ClassImp\n"
1325 "#define ClassImp(X);\n";
1326 }
1327 if (!hasCxxModules)
1328 PreIncludes += "#include <string>\n";
1329
1330 // We must include it even when we have modules because it is marked as
1331 // textual in the modulemap due to the nature of the assert header.
1332#ifndef R__WIN32
1333 PreIncludes += "#include <cassert>\n";
1334#endif
1335 PreIncludes += "using namespace std;\n";
1336 clingInterp.declare(PreIncludes);
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Initialize the cling interpreter interface.
1341/// \param name name for TInterpreter
1342/// \param title title for TInterpreter
1343/// \param argv - array of arguments passed to the cling::Interpreter constructor
1344/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1345
1346TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1347: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1348 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr),
1349 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1351{
1352 fPrompt[0] = 0;
1353 const bool fromRootCling = IsFromRootCling();
1354
1355 fCxxModulesEnabled = false;
1356#ifdef R__USE_CXXMODULES
1357 fCxxModulesEnabled = true;
1358#endif
1359
1360 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1361
1362 fTemporaries = new std::vector<cling::Value>();
1363
1364 std::vector<std::string> clingArgsStorage;
1365 clingArgsStorage.push_back("cling4root");
1366 for (const char* const* arg = argv; *arg; ++arg)
1367 clingArgsStorage.push_back(*arg);
1368
1369 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1370 if (!fromRootCling) {
1372
1373 // Add -I early so ASTReader can find the headers.
1374 std::string interpInclude(TROOT::GetEtcDir().Data());
1375 clingArgsStorage.push_back("-I" + interpInclude);
1376
1377 // Add include path to etc/cling.
1378 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1379
1380 // Add include path to etc/cling.
1381 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1382
1383 // Add the root include directory and etc/ to list searched by default.
1384 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1385
1386 // Add the current path to the include path
1387 // TCling::AddIncludePath(".");
1388
1389 // Attach the PCH (unless we have C++ modules enabled which provide the
1390 // same functionality).
1391 if (!fCxxModulesEnabled) {
1392 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1393 if (gSystem->Getenv("ROOT_PCH")) {
1394 pchFilename = gSystem->Getenv("ROOT_PCH");
1395 }
1396
1397 clingArgsStorage.push_back("-include-pch");
1398 clingArgsStorage.push_back(pchFilename);
1399 }
1400
1401 clingArgsStorage.push_back("-Wno-undefined-inline");
1402 clingArgsStorage.push_back("-fsigned-char");
1403 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1404 // See the GitHub issues #9809 and #9944
1405 // TODO: to be reviewed after the upgrade of LLVM & Clang
1406#ifndef _MSC_VER
1407 clingArgsStorage.push_back("-O1");
1408 // Disable optimized register allocation which is turned on automatically
1409 // by -O1, but seems to require -O2 to not explode in run time.
1410 clingArgsStorage.push_back("-mllvm");
1411 clingArgsStorage.push_back("-optimize-regalloc=0");
1412#endif
1413 }
1414
1415 // Process externally passed arguments if present.
1416 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1417 if (EnvOpt.has_value()) {
1418 StringRef Env(*EnvOpt);
1419 while (!Env.empty()) {
1420 StringRef Arg;
1421 std::tie(Arg, Env) = Env.split(' ');
1422 clingArgsStorage.push_back(Arg.str());
1423 }
1424 }
1425
1426 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1427 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1428 if (EnvOpt.has_value()) {
1429 StringRef Env(*EnvOpt);
1430 while (!Env.empty()) {
1431 StringRef Arg;
1432 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1433 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1434 Paths.push_back(Arg.str());
1435 }
1436 }
1437 };
1438
1439 if (fCxxModulesEnabled) {
1440 std::vector<std::string> Paths;
1441 // ROOT usually knows better where its libraries are. This way we can
1442 // discover modules without having to should thisroot.sh and should fix
1443 // gnuinstall.
1444 Paths.push_back(TROOT::GetSharedLibDir().Data());
1445 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1446 std::string EnvVarPath;
1447 for (const std::string& P : Paths)
1449 // FIXME: We should make cling -fprebuilt-module-path work.
1450 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1451 }
1452
1453 // FIXME: This only will enable frontend timing reports.
1454 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1455 if (EnvOpt.has_value())
1456 clingArgsStorage.push_back("-ftime-report");
1457
1458 // Add the overlay file. Note that we cannot factor it out for both root
1459 // and rootcling because rootcling activates modules only if -cxxmodule
1460 // flag is passed.
1461 if (fCxxModulesEnabled && !fromRootCling) {
1462 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1463 std::vector<std::string> ModuleMaps;
1464 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1465 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1466 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1467
1468 std::string cwd = gSystem->WorkingDirectory();
1469 // Give highest precedence of the modulemap in the cwd if any.
1470 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1471 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1472
1473 for (const std::string& M : ModuleMaps)
1474 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1475
1476 std::string ModulesCachePath;
1477 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1478 if (EnvOpt.has_value()){
1479 StringRef Env(*EnvOpt);
1480 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1481 ModulesCachePath = Env.str();
1482 } else {
1483 ModulesCachePath = TROOT::GetSharedLibDir();
1484 }
1485
1486 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1487 }
1488
1489 std::vector<const char*> interpArgs;
1490 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1491 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1492 interpArgs.push_back(iArg->c_str());
1493
1494 // Activate C++ modules support. If we are running within rootcling, it's up
1495 // to rootcling to set this flag depending on whether it wants to produce
1496 // C++ modules.
1497 TString vfsArg;
1498 if (fCxxModulesEnabled) {
1499 if (!fromRootCling) {
1500 // We only set this flag, rest is done by the CIFactory.
1501 interpArgs.push_back("-fmodules");
1502 interpArgs.push_back("-fno-implicit-module-maps");
1503 // We should never build modules during runtime, so let's enable the
1504 // module build remarks from clang to make it easier to spot when we do
1505 // this by accident.
1506 interpArgs.push_back("-Rmodule-build");
1507 }
1508 // ROOT implements its AutoLoading upon module's link directives. We
1509 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1510 // facilities use the link directive to dynamically load the relevant
1511 // library. So, we need to suppress clang's default autolink behavior.
1512 interpArgs.push_back("-fno-autolink");
1513 }
1514
1515#ifdef R__FAST_MATH
1516 // Same setting as in rootcling_impl.cxx.
1517 interpArgs.push_back("-ffast-math");
1518#endif
1519
1520 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1521 // Add statically injected extra arguments, usually coming from rootcling.
1522 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1523 extraArgs && *extraArgs; ++extraArgs) {
1524 if (!strcmp(*extraArgs, "-resource-dir")) {
1525 // Take the next arg as the llvm resource directory.
1526 llvmResourceDir = *(++extraArgs);
1527 } else {
1528 interpArgs.push_back(*extraArgs);
1529 }
1530 }
1531
1532 std::vector<std::string> _empty;
1533 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1534 for (const auto &arg: args)
1535 interpArgs.emplace_back(arg.c_str());
1536
1537 // Add the Rdict module file extension.
1538 cling::Interpreter::ModuleFileExtensions extensions;
1539 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1540 if (!EnvOpt.has_value())
1541 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1542
1543 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1544 &(interpArgs[0]),
1545 llvmResourceDir, extensions,
1546 interpLibHandle);
1547
1548 // Don't check whether modules' files exist.
1549 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1550 DisableValidationForModuleKind::All;
1551
1552 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1553 // to disable spell checking.
1554 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1555
1556 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1557 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1558 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1559 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1560
1561 // We need stream that doesn't close its file descriptor, thus we are not
1562 // using llvm::outs. Keeping file descriptor open we will be able to use
1563 // the results in pipes (Savannah #99234).
1564 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1565 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1566
1569
1570 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1577
1578 // Disallow auto-parsing in rootcling
1579 fIsAutoParsingSuspended = fromRootCling;
1580
1581 ResetAll();
1582
1583 // Enable dynamic lookup
1584 if (!fromRootCling) {
1585 fInterpreter->enableDynamicLookup();
1586 }
1587
1588 // Enable ClinG's DefinitionShadower for ROOT.
1589 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1590 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1591 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1592 // FIXME: We should probably switch to the default printing policy setting
1593 // after adjusting tons of reference files.
1594 Policy.SplitTemplateClosers = true;
1595 // Keep default templare arguments, required for dictionary generation.
1596 Policy.SuppressDefaultTemplateArgs = false;
1597
1598
1599 // Attach cling callbacks last; they might need TROOT::fInterpreter
1600 // and should thus not be triggered during the equivalent of
1601 // TROOT::fInterpreter = new TCling;
1602 std::unique_ptr<TClingCallbacks>
1603 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1604 fClingCallbacks = clingCallbacks.get();
1606 fInterpreter->setCallbacks(std::move(clingCallbacks));
1607
1608 if (!fromRootCling) {
1609 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1610 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1611 // e.g. because of an RPATH build.
1612 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1613 /*prepend=*/true);
1614 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1615 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1616 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1617 };
1618 // Initialize the dyld for AutoloadLibraryGenerator.
1619 DLM.initializeDyld(ShouldPermanentlyIgnore);
1620 }
1621}
1622
1623
1624////////////////////////////////////////////////////////////////////////////////
1625/// Destroy the interpreter interface.
1626
1628{
1629 // ROOT's atexit functions require the interepreter to be available.
1630 // Run them before shutting down.
1631 if (!IsFromRootCling())
1632 GetInterpreterImpl()->runAtExitFuncs();
1633 fIsShuttingDown = true;
1634 delete fMapfile;
1635 delete fRootmapFiles;
1636 delete fTemporaries;
1637 delete fNormalizedCtxt;
1638 delete fLookupHelper;
1639 gCling = nullptr;
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Initialize the interpreter, once TROOT::fInterpreter is set.
1644
1646{
1648
1649 // We are set up. Enable ROOT's AutoLoading.
1650 if (IsFromRootCling())
1651 return;
1652
1653 // Read the rules before enabling the auto loading to not inadvertently
1654 // load the libraries for the classes concerned even-though the user is
1655 // *not* using them.
1656 // Note this call must happen before the first call to LoadLibraryMap.
1657 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1658 TClass::ReadRules(); // Read the default customization rules ...
1659
1661 SetClassAutoLoading(true);
1662}
1663
1665{
1666 fIsShuttingDown = true;
1667 ResetGlobals();
1668}
1669
1670////////////////////////////////////////////////////////////////////////////////
1671/// Helper to initialize TVirtualStreamerInfo's factor early.
1672/// Use static initialization to insure only one TStreamerInfo is created.
1674{
1675 // Use lambda since SetFactory return void.
1676 auto setFactory = []() {
1678 return kTRUE;
1679 };
1680 static bool doneFactory = setFactory();
1681 return doneFactory; // avoid unused variable warning.
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685/// Register Rdict data for future loading by LoadPCM;
1686
1687void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1688{
1689 if (IsFromRootCling())
1690 return;
1691
1692 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1693 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1694 return;
1695 }
1696
1697 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1698 // a link to a non-existent file.
1699 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////
1703/// Tries to load a PCM from TFile; returns true on success.
1704
1706{
1707 auto listOfKeys = pcmFile.GetListOfKeys();
1708
1709 // This is an empty pcm
1710 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1711 ((listOfKeys->GetSize() == 1) && // only one, and
1712 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1713 ))) {
1714 return;
1715 }
1716
1717 TObjArray *protoClasses;
1718 if (gDebug > 1)
1719 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1720
1721 TObjArray *enums;
1722 pcmFile.GetObject("__Enums", enums);
1723 if (enums) {
1724 // Cache the pointers
1725 auto listOfGlobals = gROOT->GetListOfGlobals();
1726 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1727 // Loop on enums and then on enum constants
1728 for (auto selEnum : *enums) {
1729 const char *enumScope = selEnum->GetTitle();
1730 const char *enumName = selEnum->GetName();
1731 if (strcmp(enumScope, "") == 0) {
1732 // This is a global enum and is added to the
1733 // list of enums and its constants to the list of globals
1734 if (!listOfEnums->THashList::FindObject(enumName)) {
1735 ((TEnum *)selEnum)->SetClass(nullptr);
1736 listOfEnums->Add(selEnum);
1737 }
1738 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1739 if (!listOfGlobals->FindObject(enumConstant)) {
1740 listOfGlobals->Add(enumConstant);
1741 }
1742 }
1743 } else {
1744 // This enum is in a namespace. A TClass entry is bootstrapped if
1745 // none exists yet and the enum is added to it
1746 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1747 if (!nsTClassEntry) {
1748 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1749 }
1750 auto listOfEnums = nsTClassEntry->fEnums.load();
1751 if (!listOfEnums) {
1752 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1753 // For this case, the list will be immutable once constructed
1754 // (i.e. in this case, by the end of this routine).
1755 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1756 } else {
1757 // namespaces can have enums added to them
1758 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1759 }
1760 }
1761 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1762 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1763 listOfEnums->Add(selEnum);
1764 }
1765 }
1766 }
1767 enums->Clear();
1768 delete enums;
1769 }
1770
1771 pcmFile.GetObject("__ProtoClasses", protoClasses);
1772
1773 if (protoClasses) {
1774 for (auto obj : *protoClasses) {
1775 TProtoClass *proto = (TProtoClass *)obj;
1777 }
1778 // Now that all TClass-es know how to set them up we can update
1779 // existing TClasses, which might cause the creation of e.g. TBaseClass
1780 // objects which in turn requires the creation of TClasses, that could
1781 // come from the PCH, but maybe later in the loop. Instead of resolving
1782 // a dependency graph the addition to the TClassTable above allows us
1783 // to create these dependent TClasses as needed below.
1784 for (auto proto : *protoClasses) {
1785 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1786 // We have an existing TClass object. It might be emulated
1787 // or interpreted; we now have more information available.
1788 // Make that available.
1789 if (existingCl->GetState() != TClass::kHasTClassInit) {
1790 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1791 if (!dict) {
1792 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1793 } else {
1794 // This will replace the existing TClass.
1795 TClass *ncl = (*dict)();
1796 if (ncl)
1797 ncl->PostLoadCheck();
1798 }
1799 }
1800 }
1801 }
1802
1803 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1804 delete protoClasses;
1805 }
1806
1807 TObjArray *dataTypes;
1808 pcmFile.GetObject("__Typedefs", dataTypes);
1809 if (dataTypes) {
1810 for (auto typedf : *dataTypes)
1811 gROOT->GetListOfTypes()->Add(typedf);
1812 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1813 delete dataTypes;
1814 }
1815}
1816
1817////////////////////////////////////////////////////////////////////////////////
1818/// Tries to load a rdict PCM, issues diagnostics if it fails.
1819
1820void TCling::LoadPCM(std::string pcmFileNameFullPath)
1821{
1822 SuspendAutoLoadingRAII autoloadOff(this);
1823 SuspendAutoParsing autoparseOff(this);
1824 assert(!pcmFileNameFullPath.empty());
1825 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1826
1827 // Easier to work with the ROOT interfaces.
1828 TString pcmFileName = pcmFileNameFullPath;
1829
1830 // Prevent the ROOT-PCMs hitting this during auto-load during
1831 // JITting - which will cause recursive compilation.
1832 // Avoid to call the plugin manager at all.
1834
1836 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1837 if (gDebug > 5) {
1838 gDebug -= 5;
1839 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1840 } else {
1841 gDebug = 0;
1842 }
1843
1844 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1845 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1846
1847 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1848 if (pendingRdict != fPendingRdicts.end()) {
1849 llvm::StringRef pcmContent = pendingRdict->second;
1850 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1851 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1852 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1853
1854 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1855 LoadPCMImpl(pcmMemFile);
1856 // Currently the module file are never unloaded (even if the library is
1857 // unloaded) and, of course, never reloaded.
1858 // Consequently, we must NOT remove the `pendingRdict` from the list
1859 // of pending dictionary, otherwise if a library is unloaded and then
1860 // reload we will be unable to update properly the TClass object
1861 // (because we wont be able to load the rootpcm file by executing the
1862 // above lines)
1863
1864 return;
1865 }
1866
1867 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1868 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1869 pcmFileNameFullPath.data());
1870 if (!fPendingRdicts.empty())
1871 for (const auto &rdict : fPendingRdicts)
1872 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1873 rdict.first.c_str());
1874 return;
1875 }
1876
1877 if (!gROOT->IsRootFile(pcmFileName)) {
1878 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1879 return;
1880 }
1881 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1882 LoadPCMImpl(pcmFile);
1883}
1884
1885//______________________________________________________________________________
1886
1887namespace {
1888 using namespace clang;
1889
1890 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1891 // This class is to be considered an helper for autoparsing.
1892 // It visits the AST and marks all classes (in all of their redeclarations)
1893 // with the setHasExternalLexicalStorage method.
1894 public:
1895 bool VisitRecordDecl(clang::RecordDecl* rcd){
1896 if (gDebug > 2)
1897 Info("ExtLexicalStorageAdder",
1898 "Adding external lexical storage to class %s",
1899 rcd->getNameAsString().c_str());
1900 auto reDeclPtr = rcd->getMostRecentDecl();
1901 do {
1902 reDeclPtr->setHasExternalLexicalStorage();
1903 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1904
1905 return false;
1906 }
1907 };
1908
1909
1910}
1911
1912////////////////////////////////////////////////////////////////////////////////
1913///\returns true if the module map was loaded, false on error or if the map was
1914/// already loaded.
1915bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1916 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1917{
1918 assert(llvm::sys::path::is_absolute(FullPath));
1919 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1920 FileManager &FM = PP.getFileManager();
1921 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1922 // We should look for modulemap files there too.
1923 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1924 HeaderSearch &HS = PP.getHeaderSearchInfo();
1925 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1926 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1927 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1928 if (!pathExists)
1929 HSOpts.AddPrebuiltModulePath(FullPath);
1930 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1931 // because its internal call to getFile has CacheFailure set to true.
1932 // In our case, modulemaps can appear any time due to ACLiC.
1933 // Code copied from HS.lookupModuleMapFile.
1934 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1935 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1936 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1937 /*CacheFailure*/ false)) {
1938 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1939 return true;
1940 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1941 }
1942 }
1943 return false;
1944}
1945
1946////////////////////////////////////////////////////////////////////////////////
1947/// List of dicts that have the PCM information already in the PCH.
1948static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1949 "libRint",
1950 "libThread",
1951 "libRIO",
1952 "libImt",
1953 "libMultiProc",
1954 "libcomplexDict",
1955 "libdequeDict",
1956 "liblistDict",
1957 "libforward_listDict",
1958 "libvectorDict",
1959 "libmapDict",
1960 "libmultimap2Dict",
1961 "libmap2Dict",
1962 "libmultimapDict",
1963 "libsetDict",
1964 "libmultisetDict",
1965 "libunordered_setDict",
1966 "libunordered_multisetDict",
1967 "libunordered_mapDict",
1968 "libunordered_multimapDict",
1969 "libvalarrayDict",
1970 "G__GenVector32",
1971 "G__Smatrix32"};
1972
1973static void PrintDlError(const char *dyLibName, const char *modulename)
1974{
1975#ifdef R__WIN32
1976 char dyLibError[1000];
1977 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1978 dyLibError, sizeof(dyLibError), NULL);
1979#else
1980 const char *dyLibError = dlerror();
1981#endif
1982 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1983 (dyLibError) ? dyLibError : "");
1984}
1985
1986////////////////////////////////////////////////////////////////////////////////
1987// Update all the TClass registered in fClassesToUpdate
1988
1990{
1991 while (!fClassesToUpdate.empty()) {
1992 TClass *oldcl = fClassesToUpdate.back().first;
1993 // If somehow the TClass has already been loaded (maybe it was registered several time),
1994 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1995 // maybe even kForwardDeclared and needs to replaced.
1996 if (oldcl->GetState() != TClass::kHasTClassInit) {
1997 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1998 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1999 fClassesToUpdate.pop_back();
2000 // Calling func could manipulate the list so, let maintain the list
2001 // then call the dictionary function.
2002 TClass *ncl = dict();
2003 if (ncl) ncl->PostLoadCheck();
2004 } else {
2005 fClassesToUpdate.pop_back();
2006 }
2007 }
2008}
2009////////////////////////////////////////////////////////////////////////////////
2010/// Inject the module named "modulename" into cling; load all headers.
2011/// headers is a 0-terminated array of header files to `#include` after
2012/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2013/// entries (or %PATH% on Windows).
2014/// This function gets called by the static initialization of dictionary
2015/// libraries.
2016/// The payload code is injected "as is" in the interpreter.
2017/// The value of 'triggerFunc' is used to find the shared library location.
2018
2019void TCling::RegisterModule(const char* modulename,
2020 const char** headers,
2021 const char** includePaths,
2022 const char* payloadCode,
2023 const char* fwdDeclsCode,
2024 void (*triggerFunc)(),
2025 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2026 const char** classesHeaders,
2027 Bool_t lateRegistration /*=false*/,
2028 Bool_t hasCxxModule /*=false*/)
2029{
2030 const bool fromRootCling = IsFromRootCling();
2031 // We need the dictionary initialization but we don't want to inject the
2032 // declarations into the interpreter, except for those we really need for
2033 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2034 if (fromRootCling) return;
2035
2036 // When we cannot provide a module for the library we should enable header
2037 // parsing. This 'mixed' mode ensures gradual migration to modules.
2038 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2039 fHeaderParsingOnDemand = !hasCxxModule;
2040
2041 // Treat Aclic Libs in a special way. Do not delay the parsing.
2042 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2043 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2044 if (hasHeaderParsingOnDemand && isACLiC) {
2045 if (gDebug>1)
2046 Info("TCling::RegisterModule",
2047 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2048 hasHeaderParsingOnDemand = false;
2049 }
2050
2051
2052 // Make sure we relookup symbols that were search for before we loaded
2053 // their autoparse information. We could be more subtil and remove only
2054 // the failed one or only the one in this module, but for now this is
2055 // better than nothing.
2056 fLookedUpClasses.clear();
2057
2058 // Make sure we do not set off AutoLoading or autoparsing during the
2059 // module registration!
2060 SuspendAutoLoadingRAII autoLoadOff(this);
2061
2062 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2063 TCling::AddIncludePath(*inclPath);
2064 }
2065 cling::Transaction* T = nullptr;
2066 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2067 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2068 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2069 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2070 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2071 assert(cling::Interpreter::kSuccess == compRes &&
2072 "A fwd declaration could not be compiled");
2073 if (compRes!=cling::Interpreter::kSuccess){
2074 Warning("TCling::RegisterModule",
2075 "Problems in declaring string '%s' were encountered.",
2076 fwdDecl.c_str()) ;
2077 continue;
2078 }
2079
2080 // Drill through namespaces recursively until the template is found
2081 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2082 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2083 }
2084
2085 }
2086
2087 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2088 // This is used to give Sema the same view on ACLiC'ed files (which
2089 // are then #included through the dictionary) as rootcling had.
2090 TString code = gNonInterpreterClassDef;
2091 if (payloadCode)
2092 code += payloadCode;
2093
2094 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2095 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2096
2097 if (dyLibName.empty()) {
2098 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2099 return;
2100 }
2101
2102 // The triggerFunc may not be in a shared object but in an executable.
2103 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2104
2105 bool wasDlopened = false;
2106
2107 // If this call happens after dlopen has finished (i.e. late registration)
2108 // there is no need to dlopen the library recursively. See ROOT-8437 where
2109 // the dyLibName would correspond to the binary.
2110 if (!lateRegistration) {
2111
2112 if (isSharedLib) {
2113 // We need to open the dictionary shared library, to resolve symbols
2114 // requested by the JIT from it: as the library is currently being dlopen'ed,
2115 // its symbols are not yet reachable from the process.
2116 // Recursive dlopen seems to work just fine.
2117 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2118 if (dyLibHandle) {
2119 fRegisterModuleDyLibs.push_back(dyLibHandle);
2120 wasDlopened = true;
2121 } else {
2122 PrintDlError(dyLibName.c_str(), modulename);
2123 }
2124 }
2125 } // if (!lateRegistration)
2126
2127 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2128 // We now parse the forward declarations. All the classes are then modified
2129 // in order for them to have an external lexical storage.
2130 std::string fwdDeclsCodeLessEnums;
2131 {
2132 // Search for enum forward decls and only declare them if no
2133 // declaration exists yet.
2134 std::string fwdDeclsLine;
2135 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2136 std::vector<std::string> scopes;
2137 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2138 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2139 // We check if the line contains a fwd declaration of an enum
2140 if (enumPos != std::string::npos) {
2141 // We clear the scopes which we may have carried from a previous iteration
2142 scopes.clear();
2143 // We check if the enum is not in a scope. If yes, save its name
2144 // and the names of the enclosing scopes.
2145 if (enumPos != 0) {
2146 // it's enclosed in namespaces. We need to understand what they are
2147 auto nsPos = fwdDeclsLine.find("namespace");
2148 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2149 while (nsPos < enumPos && nsPos != std::string::npos) {
2150 // we have a namespace, let's put it in the collection of scopes
2151 const auto nsNameStart = nsPos + 10;
2152 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2153 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2154 scopes.push_back(nsName);
2155 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2156 }
2157 }
2158 clang::DeclContext* DC = nullptr;
2159 for (auto &&aScope: scopes) {
2160 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2161 if (!DC) {
2162 // No decl context means we have to fwd declare the enum.
2163 break;
2164 }
2165 }
2166 if (scopes.empty() || DC) {
2167 // We know the scope; let's look for the enum. For that, look
2168 // for the *last* closing parentheses of an attribute because
2169 // there can be multiple.
2170 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2171 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2172 posEnumName += 5; // skip "\"))) "
2173 while (isspace(fwdDeclsLine[posEnumName]))
2174 ++posEnumName;
2175 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2176 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2177 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2178 --posEnumNameEnd;
2179 // posEnumNameEnd now points to the last character of the name.
2180
2181 std::string enumName = fwdDeclsLine.substr(posEnumName,
2182 posEnumNameEnd - posEnumName + 1);
2183
2184 if (clang::NamedDecl* enumDecl
2185 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2186 enumName.c_str(), DC)) {
2187 // We have an existing enum decl (forward or definition);
2188 // skip this.
2189 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2190 (void)enumDecl;
2191 continue;
2192 }
2193 }
2194 }
2195
2196 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2197 }
2198 }
2199
2200 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2201 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2202 assert(cling::Interpreter::kSuccess == compRes &&
2203 "The forward declarations could not be compiled");
2204 if (compRes!=cling::Interpreter::kSuccess){
2205 Warning("TCling::RegisterModule",
2206 "Problems in compiling forward declarations for module %s: '%s'",
2207 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2208 }
2209 else if (T){
2210 // Loop over all decls in the transaction and go through them all
2211 // to mark them properly.
2212 // In order to do that, we first iterate over all the DelayedCallInfos
2213 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2214 // contained in the DelayedCallInfos. For each decl, we traverse.
2215 ExtLexicalStorageAdder elsa;
2216 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2217 cling::Transaction::DelayCallInfo& dci = *dciIt;
2218 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2219 clang::Decl* declPtr = *dit;
2220 elsa.TraverseDecl(declPtr);
2221 }
2222 }
2223 }
2224 }
2225
2226 // Now we register all the headers necessary for the class
2227 // Typical format of the array:
2228 // {"A", "classes.h", "@",
2229 // "vector<A>", "vector", "@",
2230 // "myClass", payloadCode, "@",
2231 // nullptr};
2232
2233 std::string temp;
2234 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2235 temp=*classesHeader;
2236
2237 size_t theTemplateHash = 0;
2238 bool addTemplate = false;
2239 size_t posTemplate = temp.find('<');
2240 if (posTemplate != std::string::npos) {
2241 // Add an entry for the template itself.
2242 std::string templateName = temp.substr(0, posTemplate);
2243 theTemplateHash = fStringHashFunction(templateName);
2244 addTemplate = true;
2245 }
2246 size_t theHash = fStringHashFunction(temp);
2247 classesHeader++;
2248 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2249 // This is done in order to distinguish headers from files and from the payloadCode
2250 if (payloadCode == *classesHeader_inner ){
2251 fPayloads.insert(theHash);
2252 if (addTemplate) fPayloads.insert(theTemplateHash);
2253 }
2254 if (gDebug > 2)
2255 Info("TCling::RegisterModule",
2256 "Adding a header for %s", temp.c_str());
2257 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2258 if (addTemplate) {
2259 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2260 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2261 }
2262 addTemplate = false;
2263 }
2264 }
2265 }
2266 }
2267
2268 clang::Sema &TheSema = fInterpreter->getSema();
2269
2270 bool ModuleWasSuccessfullyLoaded = false;
2271 if (hasCxxModule) {
2272 std::string ModuleName = modulename;
2273 if (llvm::StringRef(modulename).startswith("lib"))
2274 ModuleName = llvm::StringRef(modulename).substr(3).str();
2275
2276 // In case we are directly loading the library via gSystem->Load() without
2277 // specifying the relevant include paths we should try loading the
2278 // modulemap next to the library location.
2279 clang::Preprocessor &PP = TheSema.getPreprocessor();
2280 std::string ModuleMapName;
2281 if (isACLiC)
2282 ModuleMapName = ModuleName + ".modulemap";
2283 else
2284 ModuleMapName = "module.modulemap";
2285 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2286 ModuleMapName);
2287
2288 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2289 // modules such as GenVector32 because it needs to fall back to GenVector.
2290 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2291 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2292 if (!ModuleWasSuccessfullyLoaded) {
2293 // Only report if we found the module in the modulemap.
2294 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2295 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2296 if (moduleMap.findModule(ModuleName))
2297 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2298 }
2299 }
2300
2301 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2302 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2303 // The path dyLibName might not be absolute. This can happen if dyLibName
2304 // is linked to an executable in the same folder.
2305 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2306 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2307 llvm::sys::path::append(pcmFileNameFullPath,
2309 LoadPCM(pcmFileNameFullPath.str().str());
2310 }
2311
2312 { // scope within which diagnostics are de-activated
2313 // For now we disable diagnostics because we saw them already at
2314 // dictionary generation time. That won't be an issue with the PCMs.
2315
2316 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2317
2318#if defined(R__MUST_REVISIT)
2319#if R__MUST_REVISIT(6,2)
2320 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2321#endif
2322#endif
2323
2324 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2325 SuspendAutoParsing autoParseRaii(this);
2326
2327 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2328 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2329 if (isACLiC) {
2330 // Register an unload point.
2331 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2332 }
2333
2334 assert(cling::Interpreter::kSuccess == compRes &&
2335 "Payload code of a dictionary could not be parsed correctly.");
2336 if (compRes!=cling::Interpreter::kSuccess) {
2337 Warning("TCling::RegisterModule",
2338 "Problems declaring payload for module %s.", modulename) ;
2339 }
2340 }
2341 }
2342
2343 // Now that all the header have been registered/compiled, let's
2344 // make sure to 'reset' the TClass that have a class init in this module
2345 // but already had their type information available (using information/header
2346 // loaded from other modules or from class rules or from opening a TFile
2347 // or from loading header in a way that did not provoke the loading of
2348 // the library we just loaded).
2350
2351 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2352 // __ROOTCLING__ might be pulled in through PCH
2353 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2354 "#undef __ROOTCLING__\n"
2355 + gInterpreterClassDef +
2356 "#endif");
2357 }
2358
2359 if (wasDlopened) {
2360 assert(isSharedLib);
2361 void* dyLibHandle = fRegisterModuleDyLibs.back();
2362 fRegisterModuleDyLibs.pop_back();
2363 dlclose(dyLibHandle);
2364 }
2365}
2366
2368 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2369 ASTContext &C = CI.getASTContext();
2370
2371 // Do not do anything if we have no global module index.
2372 // FIXME: This is mostly to real with false positives in the TTabCom
2373 // interface for non-modules.
2374 if (!fCxxModulesEnabled)
2375 return;
2376
2377 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2378 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2379 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2380 std::string I = Ident.str();
2381 if (!Idents.Contains(I.data()))
2382 Idents.Add(new TObjString(I.c_str()));
2383 }
2384 }
2385}
2386
2387
2388////////////////////////////////////////////////////////////////////////////////
2389/// Register classes that already existed prior to their dictionary loading
2390/// and that already had a ClassInfo (and thus would not be refresh via
2391/// UpdateClassInfo.
2392
2394{
2395 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2396}
2397
2398////////////////////////////////////////////////////////////////////////////////
2399/// If the dictionary is loaded, we can remove the class from the list
2400/// (otherwise the class might be loaded twice).
2401
2403{
2404 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2405 iterator stop = fClassesToUpdate.end();
2406 for(iterator i = fClassesToUpdate.begin();
2407 i != stop;
2408 ++i)
2409 {
2410 if ( i->first == oldcl ) {
2411 fClassesToUpdate.erase(i);
2412 return;
2413 }
2414 }
2415}
2416
2417
2418////////////////////////////////////////////////////////////////////////////////
2419/// Let cling process a command line.
2420///
2421/// If the command is executed and the error is 0, then the return value
2422/// is the int value corresponding to the result of the executed command
2423/// (float and double return values will be truncated).
2424///
2425
2426// Method for handling the interpreter exceptions.
2427// the MetaProcessor is passing in as argument to teh function, because
2428// cling::Interpreter::CompilationResult is a nested class and it cannot be
2429// forward declared, thus this method cannot be a static member function
2430// of TCling.
2431
2432static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2433 const char* input_line,
2434 cling::Interpreter::CompilationResult& compRes,
2435 cling::Value* result)
2436{
2437 try {
2438 return metaProcessor->process(input_line, compRes, result);
2439 }
2440 catch (cling::InterpreterException& ex)
2441 {
2442 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2443 ex.diagnose();
2444 compRes = cling::Interpreter::kFailure;
2445 }
2446 return 0;
2447}
2448
2449////////////////////////////////////////////////////////////////////////////////
2450
2451bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2452{
2453 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2454 ie->diagnose();
2455 return true;
2456 }
2457 return false;
2458}
2459
2460////////////////////////////////////////////////////////////////////////////////
2461
2463{
2464 // Copy the passed line, it comes from a static buffer in TApplication
2465 // which can be reentered through the Cling evaluation routines,
2466 // which would overwrite the static buffer and we would forget what we
2467 // were doing.
2468 //
2469 TString sLine(line);
2470 if (strstr(line,fantomline)) {
2471 // End-Of-Line action
2472 // See the comment (copied from above):
2473 // It is a "fantom" method to synchronize user keyboard input
2474 // and ROOT prompt line (for WIN32)
2475 // and is implemented by
2476 if (gApplication) {
2477 if (gApplication->IsCmdThread()) {
2479 gROOT->SetLineIsProcessing();
2480
2482
2483 gROOT->SetLineHasBeenProcessed();
2484 }
2485 }
2486 return 0;
2487 }
2488
2490 gGlobalMutex->Lock();
2491 if (!gInterpreterMutex)
2494 }
2496 gROOT->SetLineIsProcessing();
2497
2498 struct InterpreterFlagsRAII {
2499 cling::Interpreter* fInterpreter;
2500 bool fWasDynamicLookupEnabled;
2501
2502 InterpreterFlagsRAII(cling::Interpreter* interp):
2503 fInterpreter(interp),
2504 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2505 {
2506 fInterpreter->enableDynamicLookup(true);
2507 }
2508 ~InterpreterFlagsRAII() {
2509 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2510 gROOT->SetLineHasBeenProcessed();
2511 }
2512 } interpreterFlagsRAII(GetInterpreterImpl());
2513
2514 // A non-zero returned value means the given line was
2515 // not a complete statement.
2516 int indent = 0;
2517 // This will hold the resulting value of the evaluation the given line.
2518 cling::Value result;
2519 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2520 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2521 !strncmp(sLine.Data(), ".X", 2)) {
2522 // If there was a trailing "+", then CINT compiled the code above,
2523 // and we will need to strip the "+" before passing the line to cling.
2524 TString mod_line(sLine);
2525 TString aclicMode;
2526 TString arguments;
2527 TString io;
2528 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2529 aclicMode, arguments, io);
2530 if (aclicMode.Length()) {
2531 // Remove the leading '+'
2532 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2533 aclicMode[0]='k'; // We always want to keep the .so around.
2534 if (aclicMode[1]=='+') {
2535 // We have a 2nd +
2536 aclicMode[1]='f'; // We want to force the recompilation.
2537 }
2538 if (!gSystem->CompileMacro(fname,aclicMode)) {
2539 // ACLiC failed.
2540 compRes = cling::Interpreter::kFailure;
2541 } else {
2542 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2543 // if execution was requested.
2544
2545 if (arguments.Length() == 0) {
2546 arguments = "()";
2547 }
2548 // We need to remove the extension.
2549 Ssiz_t ext = fname.Last('.');
2550 if (ext != kNPOS) {
2551 fname.Remove(ext);
2552 }
2553 const char *function = gSystem->BaseName(fname);
2554 mod_line = function + arguments + io;
2556 }
2557 }
2558 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2559 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2560 if (gSystem->Load(fname) < 0) {
2561 // Loading failed.
2562 compRes = cling::Interpreter::kFailure;
2563 } else {
2564 if (arguments.Length() == 0) {
2565 arguments = "()";
2566 }
2567 // We need to remove the extension. (*.so or *.dll)
2568 Ssiz_t ext = fname.Last('.');
2569 if (ext != kNPOS) {
2570 fname.Remove(ext);
2571 }
2572 // Now we try to find the 'main' function to run within this shared library
2573 // We distinguish two cases: a library.so with a function library(args),
2574 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2575 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2576 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2577 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2578 ext = fname.Last('_');
2579 if (ext != kNPOS) {
2580 fname.Remove(ext);
2581 }
2582 }
2583 const char *function = gSystem->BaseName(fname);
2584 mod_line = function + arguments + io;
2586 }
2587 } else {
2588 // neither ACLiC nor run shared-library (.x)
2589 size_t unnamedMacroOpenCurly;
2590 {
2591 std::string code;
2592 std::string codeline;
2593 // Windows requires std::ifstream::binary to properly handle
2594 // CRLF and LF line endings
2595 std::ifstream in(fname, std::ifstream::binary);
2596 while (in) {
2597 std::getline(in, codeline);
2598 code += codeline + "\n";
2599 }
2600 unnamedMacroOpenCurly
2601 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2602 }
2603
2604 fCurExecutingMacros.push_back(fname);
2605 if (unnamedMacroOpenCurly != std::string::npos) {
2606 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2607 unnamedMacroOpenCurly);
2608 } else {
2609 // No DynLookup for .x, .L of named macros.
2610 fInterpreter->enableDynamicLookup(false);
2612 }
2613 fCurExecutingMacros.pop_back();
2614 }
2615 } // .L / .X / .x
2616 else {
2617 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2618 // explicitly ignore .autodict without having to support it
2619 // in cling.
2620
2621 // Turn off autoparsing if this is an include directive
2622 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2623 if (isInclusionDirective) {
2624 SuspendAutoParsing autoParseRaii(this);
2626 } else {
2628 }
2629 }
2630 }
2631 if (result.isValid())
2633 if (indent) {
2634 if (error)
2635 *error = kProcessing;
2636 return 0;
2637 }
2638 if (error) {
2639 switch (compRes) {
2640 case cling::Interpreter::kSuccess: *error = kNoError; break;
2641 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2642 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2643 }
2644 }
2645 if (compRes == cling::Interpreter::kSuccess
2646 && result.isValid()
2647 && !result.isVoid())
2648 {
2649 return result.castAs<Longptr_t>();
2650 }
2651 return 0;
2652}
2653
2654////////////////////////////////////////////////////////////////////////////////
2655/// No-op; see TRint instead.
2656
2658{
2659}
2660
2661////////////////////////////////////////////////////////////////////////////////
2662/// \brief Add a directory to the list of directories in which the
2663/// interpreter looks for include files.
2664/// \param[in] path The path to the directory.
2665/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2666/// \b NOT supported.
2667/// \warning Only the path to the directory should be specified, without
2668/// prepending the \c -I prefix, i.e.
2669/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2670/// \c -I prefix is used it will be ignored.
2671void TCling::AddIncludePath(const char *path)
2672{
2674 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2675 // gCling->AddIncludePath() does not! Work around that inconsistency:
2676 if (path[0] == '-' && path[1] == 'I')
2677 path += 2;
2678 TString sPath(path);
2679 gSystem->ExpandPathName(sPath);
2680#ifdef _MSC_VER
2681 if (sPath.BeginsWith("/")) {
2682 char drive[3];
2683 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2684 sPath.Prepend(drive);
2685 }
2686#endif
2687 fInterpreter->AddIncludePath(sPath.Data());
2688}
2689
2690////////////////////////////////////////////////////////////////////////////////
2691/// Visit all members over members, recursing over base classes.
2692
2693void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2694 const TClass* cl, Bool_t isTransient)
2695{
2699 }
2700
2701 if (!cl || cl->GetCollectionProxy()) {
2702 // We do not need to investigate the content of the STL
2703 // collection, they are opaque to us (and details are
2704 // uninteresting).
2705 return;
2706 }
2707
2708 static const TClassRef clRefString("std::string");
2709 if (clRefString == cl) {
2710 // We stream std::string without going through members..
2711 return;
2712 }
2713
2714 if (TClassEdit::IsStdArray(cl->GetName())) {
2715 // We treat std arrays as C arrays
2716 return;
2717 }
2718
2719 const char* cobj = (const char*) obj; // for ptr arithmetics
2720
2721 // Treat the case of std::complex in a special manner. We want to enforce
2722 // the layout of a stl implementation independent class, which is the
2723 // complex as implemented in ROOT5.
2724
2725 // A simple lambda to simplify the code
2726 auto inspInspect = [&] (ptrdiff_t offset){
2727 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2728 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2729 };
2730
2731 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2732 switch(complexType) {
2734 {
2735 break;
2736 }
2738 {
2739 inspInspect(sizeof(float));
2740 return;
2741 }
2743 {
2744 inspInspect(sizeof(double));
2745 return;
2746 }
2748 {
2749 inspInspect(sizeof(int));
2750 return;
2751 }
2753 {
2754 inspInspect(sizeof(long));
2755 return;
2756 }
2757 }
2758
2759 static clang::PrintingPolicy
2760 printPol(fInterpreter->getCI()->getLangOpts());
2761 if (printPol.Indentation) {
2762 // not yet initialized
2763 printPol.Indentation = 0;
2764 printPol.SuppressInitializers = true;
2765 }
2766
2767 const char* clname = cl->GetName();
2768 // Printf("Inspecting class %s\n", clname);
2769
2770 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2771 const clang::Decl *scopeDecl = nullptr;
2772 const clang::Type *recordType = nullptr;
2773
2774 if (cl->GetClassInfo()) {
2775 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2776 scopeDecl = clingCI->GetDecl();
2777 recordType = clingCI->GetType();
2778 } else {
2779 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2780 // Diags will complain about private classes:
2781 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2782 &recordType);
2783 }
2784 if (!scopeDecl) {
2785 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2786 return;
2787 }
2788 const clang::CXXRecordDecl* recordDecl
2789 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2790 if (!recordDecl) {
2791 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2792 return;
2793 }
2794
2795 {
2796 // Force possible deserializations first. We need to have no pending
2797 // Transaction when passing control flow to the inspector below (ROOT-7779).
2798 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2799
2800 astContext.getASTRecordLayout(recordDecl);
2801
2802 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2803 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2804 }
2805
2806 const clang::ASTRecordLayout& recLayout
2807 = astContext.getASTRecordLayout(recordDecl);
2808
2809 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2810 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2811 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2812 // cl->GetName());
2813 // }
2814 if (cl->Size() != recLayout.getSize().getQuantity()) {
2815 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2816 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2817 }
2818
2819 unsigned iNField = 0;
2820 // iterate over fields
2821 // FieldDecls are non-static, else it would be a VarDecl.
2822 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2823 eField = recordDecl->field_end(); iField != eField;
2824 ++iField, ++iNField) {
2825
2826
2827 clang::QualType memberQT = iField->getType();
2828 if (recordType) {
2829 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2830 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2831 }
2832 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2833 if (memberQT.isNull()) {
2834 std::string memberName;
2835 llvm::raw_string_ostream stream(memberName);
2836 // Don't trigger fopen of the source file to count lines:
2837 printPol.AnonymousTagLocations = false;
2838 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2839 stream.flush();
2840 Error("InspectMembers",
2841 "Cannot retrieve QualType for member %s while inspecting class %s",
2842 memberName.c_str(), clname);
2843 continue; // skip member
2844 }
2845 const clang::Type* memType = memberQT.getTypePtr();
2846 if (!memType) {
2847 std::string memberName;
2848 llvm::raw_string_ostream stream(memberName);
2849 // Don't trigger fopen of the source file to count lines:
2850 printPol.AnonymousTagLocations = false;
2851 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2852 stream.flush();
2853 Error("InspectMembers",
2854 "Cannot retrieve Type for member %s while inspecting class %s",
2855 memberName.c_str(), clname);
2856 continue; // skip member
2857 }
2858
2859 const clang::Type* memNonPtrType = memType;
2860 Bool_t ispointer = false;
2861 if (memNonPtrType->isPointerType()) {
2862 ispointer = true;
2863 clang::QualType ptrQT
2864 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2865 if (recordType) {
2866 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2867 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2868 }
2869 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2870 if (ptrQT.isNull()) {
2871 std::string memberName;
2872 llvm::raw_string_ostream stream(memberName);
2873 // Don't trigger fopen of the source file to count lines:
2874 printPol.AnonymousTagLocations = false;
2875 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2876 stream.flush();
2877 Error("InspectMembers",
2878 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2879 memberName.c_str(), clname);
2880 continue; // skip member
2881 }
2882 memNonPtrType = ptrQT.getTypePtr();
2883 }
2884
2885 // assemble array size(s): "[12][4][]"
2886 llvm::SmallString<8> arraySize;
2887 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2888 unsigned arrLevel = 0;
2889 bool haveErrorDueToArray = false;
2890 while (arrType) {
2891 ++arrLevel;
2892 arraySize += '[';
2893 const clang::ConstantArrayType* constArrType =
2894 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2895 if (constArrType) {
2896 constArrType->getSize().toStringUnsigned(arraySize);
2897 }
2898 arraySize += ']';
2899 clang::QualType subArrQT = arrType->getElementType();
2900 if (subArrQT.isNull()) {
2901 std::string memberName;
2902 llvm::raw_string_ostream stream(memberName);
2903 // Don't trigger fopen of the source file to count lines:
2904 printPol.AnonymousTagLocations = false;
2905 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2906 stream.flush();
2907 Error("InspectMembers",
2908 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2909 arrLevel, subArrQT.getAsString(printPol).c_str(),
2910 memberName.c_str(), clname);
2911 haveErrorDueToArray = true;
2912 break;
2913 }
2914 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2915 }
2916 if (haveErrorDueToArray) {
2917 continue; // skip member
2918 }
2919
2920 // construct member name
2921 std::string fieldName;
2922 if (memType->isPointerType()) {
2923 fieldName = "*";
2924 }
2925
2926 // Check if this field has a custom ioname, if not, just use the one of the decl
2927 std::string ioname(iField->getName());
2928 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2929 fieldName += ioname;
2930 fieldName += arraySize;
2931
2932 // get member offset
2933 // NOTE currently we do not support bitfield and do not support
2934 // member that are not aligned on 'bit' boundaries.
2935 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2936 ptrdiff_t fieldOffset = offset.getQuantity();
2937
2938 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2939 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2940 // R__insp.InspectMember(fName, "fName.");
2941 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2942
2943 // If the class has a custom streamer and the type of the filed is a
2944 // private enum, struct or class, skip it.
2945 if (!insp.IsTreatingNonAccessibleTypes()){
2946 auto iFiledQtype = iField->getType();
2947 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2948 auto declAccess = tagDecl->getAccess();
2949 if (declAccess == AS_private || declAccess == AS_protected) {
2950 continue;
2951 }
2952 }
2953 }
2954
2955 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2956
2957 if (!ispointer) {
2958 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2959 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2960 // nested objects get an extra call to InspectMember
2961 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2962 std::string sFieldRecName;
2963 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2965 clang::QualType(memNonPtrType,0),
2966 *fInterpreter,
2968 }
2969
2970 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2971 // if we can not find the member (which should not really happen),
2972 // let's consider it transient.
2973 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2974
2975 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2976 (fieldName + '.').c_str(), transient);
2977
2978 }
2979 }
2980 } // loop over fields
2981
2982 // inspect bases
2983 // TNamed::ShowMembers(R__insp);
2984 unsigned iNBase = 0;
2985 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2986 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2987 iBase != eBase; ++iBase, ++iNBase) {
2988 clang::QualType baseQT = iBase->getType();
2989 if (baseQT.isNull()) {
2990 Error("InspectMembers",
2991 "Cannot find QualType for base number %d while inspecting class %s",
2992 iNBase, clname);
2993 continue;
2994 }
2995 const clang::CXXRecordDecl* baseDecl
2996 = baseQT->getAsCXXRecordDecl();
2997 if (!baseDecl) {
2998 Error("InspectMembers",
2999 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3000 iNBase, clname);
3001 continue;
3002 }
3003 TClass* baseCl=nullptr;
3004 std::string sBaseName;
3005 // Try with the DeclId
3006 std::vector<TClass*> foundClasses;
3007 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3008 if (foundClasses.size()==1){
3009 baseCl=foundClasses[0];
3010 } else {
3011 // Try with the normalised Name, as a fallback
3012 if (!baseCl){
3014 baseQT,
3015 *fInterpreter,
3017 baseCl = TClass::GetClass(sBaseName.c_str());
3018 }
3019 }
3020
3021 if (!baseCl){
3022 std::string qualNameForDiag;
3023 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3024 Error("InspectMembers",
3025 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3026 continue;
3027 }
3028
3029 int64_t baseOffset;
3030 if (iBase->isVirtual()) {
3032 if (!isTransient) {
3033 Error("InspectMembers",
3034 "Base %s of class %s is virtual but no object provided",
3035 sBaseName.c_str(), clname);
3036 }
3038 } else {
3039 // We have an object to determine the vbase offset.
3041 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3042 if (ci && baseCi) {
3043 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3044 true /*isDerivedObj*/);
3045 if (baseOffset == -1) {
3046 Error("InspectMembers",
3047 "Error calculating offset of virtual base %s of class %s",
3048 sBaseName.c_str(), clname);
3049 }
3050 } else {
3051 Error("InspectMembers",
3052 "Cannot calculate offset of virtual base %s of class %s",
3053 sBaseName.c_str(), clname);
3054 continue;
3055 }
3056 }
3057 } else {
3058 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3059 }
3060 // TOFIX: baseCl can be null here!
3061 if (baseCl->IsLoaded()) {
3062 // For loaded class, CallShowMember will (especially for TObject)
3063 // call the virtual ShowMember rather than the class specific version
3064 // resulting in an infinite recursion.
3065 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3066 } else {
3067 baseCl->CallShowMembers(cobj + baseOffset,
3068 insp, isTransient);
3069 }
3070 } // loop over bases
3071}
3072
3073////////////////////////////////////////////////////////////////////////////////
3074/// Reset the interpreter internal state in case a previous action was not correctly
3075/// terminated.
3076
3078{
3079 // No-op there is not equivalent state (to be cleared) in Cling.
3080}
3081
3082////////////////////////////////////////////////////////////////////////////////
3083/// Delete existing temporary values.
3084
3086{
3087 // No-op for cling due to cling::Value.
3088}
3089
3090////////////////////////////////////////////////////////////////////////////////
3091/// Declare code to the interpreter, without any of the interpreter actions
3092/// that could trigger a re-interpretation of the code. I.e. make cling
3093/// behave like a compiler: no dynamic lookup, no input wrapping for
3094/// subsequent execution, no automatic provision of declarations but just a
3095/// plain `#include`.
3096/// Returns true on success, false on failure.
3097
3098bool TCling::Declare(const char* code)
3099{
3101
3102 SuspendAutoLoadingRAII autoLoadOff(this);
3103 SuspendAutoParsing autoParseRaii(this);
3104
3105 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3106 fInterpreter->enableDynamicLookup(false);
3107 bool oldRawInput = fInterpreter->isRawInputEnabled();
3108 fInterpreter->enableRawInput(true);
3109
3110 Bool_t ret = LoadText(code);
3111
3112 fInterpreter->enableRawInput(oldRawInput);
3113 fInterpreter->enableDynamicLookup(oldDynLookup);
3114 return ret;
3115}
3116
3117////////////////////////////////////////////////////////////////////////////////
3118/// It calls a "fantom" method to synchronize user keyboard input
3119/// and ROOT prompt line.
3120
3122{
3124}
3125
3126// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3127// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3128// was already taking a lock.
3129static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3130{
3131 // Check shared library.
3132 TString tLibName(libname);
3133 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3134 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3135 return false;
3136}
3137
3138Bool_t TCling::IsLibraryLoaded(const char* libname) const
3139{
3141 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3142}
3143
3144////////////////////////////////////////////////////////////////////////////////
3145/// Return true if ROOT has cxxmodules pcm for a given library name.
3146// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3147Bool_t TCling::HasPCMForLibrary(const char *libname) const
3148{
3149 llvm::StringRef ModuleName(libname);
3150 ModuleName = llvm::sys::path::stem(ModuleName);
3151 ModuleName.consume_front("lib");
3152
3153 // FIXME: In case when the modulemap is not yet loaded we will return the
3154 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3155 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3156 // which may happen after calling this interface. Maybe we should also check
3157 // if there is a Event.pcm file and a module.modulemap, load it and return
3158 // true.
3159 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3160 clang::Module *M = moduleMap.findModule(ModuleName);
3161 return M && !M->IsUnimportable && M->getASTFile();
3162}
3163
3164////////////////////////////////////////////////////////////////////////////////
3165/// Return true if the file has already been loaded by cint.
3166/// We will try in this order:
3167/// actual filename
3168/// filename as a path relative to
3169/// the include path
3170/// the shared library path
3171
3173{
3175
3176 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3177 // cling::DynamicLibraryManager.
3178
3179 std::string file_name = filename;
3180 size_t at = std::string::npos;
3181 while ((at = file_name.find("/./")) != std::string::npos)
3182 file_name.replace(at, 3, "/");
3183
3184 std::string filesStr = "";
3185 llvm::raw_string_ostream filesOS(filesStr);
3186 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3187 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3188 filesOS.flush();
3189
3190 llvm::SmallVector<llvm::StringRef, 100> files;
3191 llvm::StringRef(filesStr).split(files, "\n");
3192
3193 std::set<std::string> fileMap;
3194 llvm::StringRef file_name_ref(file_name);
3195 // Fill fileMap; return early on exact match.
3196 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3197 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3198 if ((*iF) == file_name_ref) return kTRUE; // exact match
3199 fileMap.insert(iF->str());
3200 }
3201
3202 if (fileMap.empty()) return kFALSE;
3203
3204 // Check MacroPath.
3205 TString sFilename(file_name.c_str());
3207 && fileMap.count(sFilename.Data())) {
3208 return kTRUE;
3209 }
3210
3211 // Check IncludePath.
3212 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3213 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3214 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3215 while (incPath.Index(" :") != -1) {
3216 incPath.ReplaceAll(" :", ":");
3217 }
3218 incPath.Prepend(".:");
3219 sFilename = file_name.c_str();
3220 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3221 && fileMap.count(sFilename.Data())) {
3222 return kTRUE;
3223 }
3224
3225 // Check shared library.
3226 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3227 return kTRUE;
3228
3229 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3230 clang::ConstSearchDirIterator *CurDir = nullptr;
3231 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3232 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3233 auto FE = HS.LookupFile(file_name.c_str(),
3234 clang::SourceLocation(),
3235 /*isAngled*/ false,
3236 /*FromDir*/ nullptr, CurDir,
3237 clang::ArrayRef<std::pair<const clang::FileEntry *,
3238 const clang::DirectoryEntry *>>(),
3239 /*SearchPath*/ nullptr,
3240 /*RelativePath*/ nullptr,
3241 /*RequestingModule*/ nullptr,
3242 /*SuggestedModule*/ nullptr,
3243 /*IsMapped*/ nullptr,
3244 /*IsFrameworkFound*/ nullptr,
3245 /*SkipCache*/ false,
3246 /*BuildSystemModule*/ false,
3247 /*OpenFile*/ false,
3248 /*CacheFail*/ false);
3249 if (FE) {
3250 // check in the source manager if the file is actually loaded
3251 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3252 // this works only with header (and source) files...
3253 clang::FileID FID = SM.translateFile(*FE);
3254 if (!FID.isInvalid() && FID.getHashValue() == 0)
3255 return kFALSE;
3256 else {
3257 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3258 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3259 return kFALSE;
3260 if (!FID.isInvalid())
3261 return kTRUE;
3262 }
3263 // ...then check shared library again, but with full path now
3264 sFilename = FE->getName().str();
3265 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3266 && fileMap.count(sFilename.Data())) {
3267 return kTRUE;
3268 }
3269 }
3270 return kFALSE;
3271}
3272
3273
3274#if defined(R__MACOSX)
3275
3276////////////////////////////////////////////////////////////////////////////////
3277/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3278/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3279/// to `-lFOO` such that it can be passed to the linker.
3280/// This is a unique feature of macOS 11.
3281
3282static bool R__UpdateLibFileForLinking(TString &lib)
3283{
3284 const char *mapfile = nullptr;
3285#if __x86_64__
3286 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3287#elif __arm64__
3288 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3289#else
3290 #error unsupported architecture
3291#endif
3292 if (std::ifstream cacheMap{mapfile}) {
3293 std::string line;
3294 while (getline(cacheMap, line)) {
3295 if (line.find(lib) != std::string::npos) {
3296 lib.ReplaceAll("/usr/lib/lib","-l");
3297 lib.ReplaceAll(".dylib","");
3298 return true;
3299 }
3300 }
3301 return false;
3302 }
3303 return false;
3304}
3305#endif // R__MACOSX
3306
3307#if defined (R__LINUX) || defined (R__FBSD)
3308
3309////////////////////////////////////////////////////////////////////////////////
3310/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3311/// Collects opened libraries.
3312
3313static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3314{
3315 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3316 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3317
3318 auto newLibs = static_cast<std::vector<std::string>*>(data);
3319 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3320 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3321 if (info->dlpi_name && info->dlpi_name[0]
3322#if defined(R__FBSD)
3323 //skip the executable (with null addr)
3324 && info->dlpi_addr
3325 //has no path
3326 && strncmp(info->dlpi_name, "[vdso]", 6)
3327 //the linker does not like to be mmapped
3328 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3329 //with error message "mmap of entire address space failed: Cannot allocate memory"
3330 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3331#endif
3332 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3333 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3334 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3335 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3336 newLibs->emplace_back(info->dlpi_name);
3337 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3338 }
3339 // No matter what the doc says, return != 0 means "stop the iteration".
3340 return 0;
3341}
3342
3343#endif // R__LINUX || R__FBSD
3344
3345
3346////////////////////////////////////////////////////////////////////////////////
3347
3349{
3350#if defined(R__WIN32) || defined(__CYGWIN__)
3351 HMODULE hModules[1024];
3352 void *hProcess;
3353 unsigned long cbModules;
3354 unsigned int i;
3355 hProcess = (void *)::GetCurrentProcess();
3356 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3357 // start at 1 to skip the executable itself
3358 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3359 static const int bufsize = 260;
3360 wchar_t winname[bufsize];
3361 char posixname[bufsize];
3362 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3363#if defined(__CYGWIN__)
3364 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3365#else
3366 std::wstring wpath = winname;
3367 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3368 string path(wpath.begin(), wpath.end());
3369 strncpy(posixname, path.c_str(), bufsize);
3370#endif
3371 if (!fSharedLibs.Contains(posixname)) {
3372 RegisterLoadedSharedLibrary(posixname);
3373 }
3374 }
3375#elif defined(R__MACOSX)
3376 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3377 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3378
3379 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3380 // Skip non-dylibs
3381 if (mh->filetype == MH_DYLIB) {
3382 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3383 RegisterLoadedSharedLibrary(imageName);
3384 }
3385 }
3386
3387 ++imageIndex;
3388 }
3389 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3390#elif defined(R__LINUX) || defined(R__FBSD)
3391 // fPrevLoadedDynLibInfo is unused on Linux.
3392 (void) fPrevLoadedDynLibInfo;
3393
3394 std::vector<std::string> newLibs;
3395 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3396 for (auto &&lib: newLibs)
3397 RegisterLoadedSharedLibrary(lib.c_str());
3398#else
3399 Error("TCling::UpdateListOfLoadedSharedLibraries",
3400 "Platform not supported!");
3401#endif
3402}
3403
3404namespace {
3405template <int N>
3406static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3407 return !strncmp(haystack, needle, N - 1);
3408}
3409}
3410
3411////////////////////////////////////////////////////////////////////////////////
3412/// Register a new shared library name with the interpreter; add it to
3413/// fSharedLibs.
3414
3416{
3417 // Ignore NULL filenames, aka "the process".
3418 if (!filename) return;
3419
3420 // Tell the interpreter that this library is available; all libraries can be
3421 // used to resolve symbols.
3422 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3423 if (!DLM->isLibraryLoaded(filename)) {
3424 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3425 }
3426
3427#if defined(R__MACOSX)
3428 // Check that this is not a system library that does not exist on disk.
3429 auto lenFilename = strlen(filename);
3430 auto isInMacOSSystemDir = [](const char *fn) {
3431 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3432 };
3433 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3434
3435 // These we should not link with (e.g. because they forward to .tbd):
3436 || StartsWithStrLit(filename, "/usr/lib/system/")
3437 || StartsWithStrLit(filename, "/usr/lib/libc++")
3438 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3439 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3440 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3441 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3442 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3443 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3444 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3445 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3446 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3447 || StartsWithStrLit(filename, "/usr/lib/libauto")
3448 || StartsWithStrLit(filename, "/usr/lib/libcups")
3449 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3450 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3451 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3452 || StartsWithStrLit(filename, "/usr/lib/libpam")
3453 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3454 || StartsWithStrLit(filename, "/usr/lib/libextension")
3455 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3456 || StartsWithStrLit(filename, "/usr/lib/liboah")
3457 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3458 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3459 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3460 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3461
3462 // The system lib is likely in macOS's blob.
3463 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3464
3465 // "Link against the umbrella framework 'System.framework' instead"
3466 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3467 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3468 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3469
3470 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3471 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3472 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3473 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3474 return;
3475 TString sFileName(filename);
3476 R__UpdateLibFileForLinking(sFileName);
3477 filename = sFileName.Data();
3478#elif defined(__CYGWIN__)
3479 // Check that this is not a system library
3480 static const int bufsize = 260;
3481 char posixwindir[bufsize];
3482 char *windir = getenv("WINDIR");
3483 if (windir)
3484 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3485 else
3486 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3487 if (strstr(filename, posixwindir) ||
3488 strstr(filename, "/usr/bin/cyg"))
3489 return;
3490#elif defined(R__WIN32)
3491 if (strstr(filename, "/Windows/"))
3492 return;
3493#elif defined (R__LINUX)
3494 if (strstr(filename, "/ld-linux")
3495 || strstr(filename, "linux-gnu/")
3496 || strstr(filename, "/libstdc++.")
3497 || strstr(filename, "/libgcc")
3498 || strstr(filename, "/libc.")
3499 || strstr(filename, "/libdl.")
3500 || strstr(filename, "/libm."))
3501 return;
3502#endif
3503 // Update string of available libraries.
3504 if (!fSharedLibs.IsNull()) {
3505 fSharedLibs.Append(" ");
3506 }
3508}
3509
3510////////////////////////////////////////////////////////////////////////////////
3511/// Load a library file in cling's memory.
3512/// if 'system' is true, the library is never unloaded.
3513/// Return 0 on success, -1 on failure.
3514
3515Int_t TCling::Load(const char* filename, Bool_t system)
3516{
3517 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3518
3519 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3521 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3522 std::string canonLib = DLM->lookupLibrary(filename);
3523 cling::DynamicLibraryManager::LoadLibResult res
3524 = cling::DynamicLibraryManager::kLoadLibNotFound;
3525 if (!canonLib.empty()) {
3526 if (system)
3527 res = DLM->loadLibrary(filename, system, true);
3528 else {
3529 // For the non system libs, we'd like to be able to unload them.
3530 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3531 cling::Interpreter::CompilationResult compRes;
3532 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3533 if (compRes == cling::Interpreter::kSuccess)
3534 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3535 }
3536 }
3537
3538 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3540 }
3541 switch (res) {
3542 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3543 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3544 default: break;
3545 };
3546 return -1;
3547}
3548
3549////////////////////////////////////////////////////////////////////////////////
3550/// Load a macro file in cling's memory.
3551
3552void TCling::LoadMacro(const char* filename, EErrorCode* error)
3553{
3554 ProcessLine(Form(".L %s", filename), error);
3555}
3556
3557////////////////////////////////////////////////////////////////////////////////
3558/// Let cling process a command line asynch.
3559
3561{
3562 return ProcessLine(line, error);
3563}
3564
3565////////////////////////////////////////////////////////////////////////////////
3566/// Let cling process a command line synchronously, i.e we are waiting
3567/// it will be finished.
3568
3570{
3572 if (gApplication) {
3573 if (gApplication->IsCmdThread()) {
3574 return ProcessLine(line, error);
3575 }
3576 return 0;
3577 }
3578 return ProcessLine(line, error);
3579}
3580
3581////////////////////////////////////////////////////////////////////////////////
3582/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3583/// however not declarations, like "Int_t x;").
3584
3586{
3587#ifdef R__WIN32
3588 // Test on ApplicationImp not being 0 is needed because only at end of
3589 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3590 // we can not use it.
3592 while (gROOT->IsLineProcessing() && !gApplication) {
3593 Warning("Calc", "waiting for cling thread to free");
3594 gSystem->Sleep(500);
3595 }
3596 gROOT->SetLineIsProcessing();
3597 }
3598#endif // R__WIN32
3600 if (error) {
3601 *error = TInterpreter::kNoError;
3602 }
3603 cling::Value valRef;
3604 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3605 try {
3606 cr = fInterpreter->evaluate(line, valRef);
3607 }
3608 catch (cling::InterpreterException& ex)
3609 {
3610 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3611 ex.diagnose();
3612 cr = cling::Interpreter::kFailure;
3613 }
3614
3615 if (cr != cling::Interpreter::kSuccess) {
3616 // Failure in compilation.
3617 if (error) {
3618 // Note: Yes these codes are weird.
3620 }
3621 return 0L;
3622 }
3623 if (!valRef.isValid()) {
3624 // Failure at runtime.
3625 if (error) {
3626 // Note: Yes these codes are weird.
3627 *error = TInterpreter::kDangerous;
3628 }
3629 return 0L;
3630 }
3631
3632 if (valRef.isVoid()) {
3633 return 0;
3634 }
3635
3636 RegisterTemporary(valRef);
3637#ifdef R__WIN32
3639 gROOT->SetLineHasBeenProcessed();
3640 }
3641#endif // R__WIN32
3642 return valRef.castAs<Longptr_t>();
3643}
3644
3645////////////////////////////////////////////////////////////////////////////////
3646/// Set a getline function to call when input is needed.
3647
3648void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3649 void (*histaddFunc)(const char* line))
3650{
3651 // If cling offers a replacement for G__pause(), it would need to
3652 // also offer a way to customize at least the history recording.
3653
3654#if defined(R__MUST_REVISIT)
3655#if R__MUST_REVISIT(6,2)
3656 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3657#endif
3658#endif
3659}
3660
3661////////////////////////////////////////////////////////////////////////////////
3662/// Helper function to increase the internal Cling count of transactions
3663/// that change the AST.
3664
3665Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3666{
3668
3669 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3670 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3671 || T.macros_begin() != T.macros_end()
3672 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3674 return true;
3675 }
3676 return false;
3677}
3678
3679////////////////////////////////////////////////////////////////////////////////
3680/// Delete object from cling symbol table so it can not be used anymore.
3681/// cling objects are always on the heap.
3682
3684{
3685 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3686 // put in place the Read/Write part here. Keeping the write lock
3687 // here is 'catasptrophic' for scaling as it means that ALL calls
3688 // to RecursiveRemove will take the write lock and performance
3689 // of many threads trying to access the write lock at the same
3690 // time is relatively bad.
3692 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3693 // (but isn't at the moment).
3694 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3695 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3696 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3698 DeleteGlobal(obj);
3699 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3700 }
3701 }
3702}
3703
3704////////////////////////////////////////////////////////////////////////////////
3705/// Pressing Ctrl+C should forward here. In the case where we have had
3706/// continuation requested we must reset it.
3707
3709{
3710 fMetaProcessor->cancelContinuation();
3711 // Reset the Cling state to the state saved by the last call to
3712 // TCling::SaveContext().
3713#if defined(R__MUST_REVISIT)
3714#if R__MUST_REVISIT(6,2)
3716 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3717#endif
3718#endif
3719}
3720
3721////////////////////////////////////////////////////////////////////////////////
3722/// Reset the Cling state to its initial state.
3723
3725{
3726#if defined(R__MUST_REVISIT)
3727#if R__MUST_REVISIT(6,2)
3729 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3730#endif
3731#endif
3732}
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Reset in Cling the list of global variables to the state saved by the last
3736/// call to TCling::SaveGlobalsContext().
3737///
3738/// Note: Right now, all we do is run the global destructors.
3739
3741{
3743 // TODO:
3744 // Here we should iterate over the transactions (N-3) and revert.
3745 // N-3 because the first three internal to cling.
3746
3747 fInterpreter->runAndRemoveStaticDestructors();
3748}
3749
3750////////////////////////////////////////////////////////////////////////////////
3751/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3752/// call to TCling::SaveGlobalsContext().
3753
3755{
3756#if defined(R__MUST_REVISIT)
3757#if R__MUST_REVISIT(6,2)
3759 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3760#endif
3761#endif
3762}
3763
3764////////////////////////////////////////////////////////////////////////////////
3765/// Rewind Cling dictionary to the point where it was before executing
3766/// the current macro. This function is typically called after SEGV or
3767/// ctlr-C after doing a longjmp back to the prompt.
3768
3770{
3771#if defined(R__MUST_REVISIT)
3772#if R__MUST_REVISIT(6,2)
3774 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3775#endif
3776#endif
3777}
3778
3779////////////////////////////////////////////////////////////////////////////////
3780/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3781/// Returns 1 in case of success and 0 in case object was not in table.
3782
3784{
3785#if defined(R__MUST_REVISIT)
3786#if R__MUST_REVISIT(6,2)
3788 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3789#endif
3790#endif
3791 return 0;
3792}
3793
3794////////////////////////////////////////////////////////////////////////////////
3795/// Undeclare obj called name.
3796/// Returns 1 in case of success, 0 for failure.
3797
3799{
3800#if defined(R__MUST_REVISIT)
3801#if R__MUST_REVISIT(6,2)
3802 Warning("DeleteVariable","should do more that just reseting the value to zero");
3803#endif
3804#endif
3805
3807 llvm::StringRef srName(name);
3808 const char* unscopedName = name;
3809 llvm::StringRef::size_type posScope = srName.rfind("::");
3810 const clang::DeclContext* declCtx = nullptr;
3811 if (posScope != llvm::StringRef::npos) {
3812 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3813 const clang::Decl* scopeDecl
3814 = lh.findScope(srName.substr(0, posScope),
3815 cling::LookupHelper::WithDiagnostics);
3816 if (!scopeDecl) {
3817 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3818 name);
3819 return 0;
3820 }
3821 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3822 if (!declCtx) {
3823 Error("DeleteVariable",
3824 "Enclosing scope for variable %s is not a declaration context",
3825 name);
3826 return 0;
3827 }
3828 unscopedName += posScope + 2;
3829 }
3830 // Could trigger deserialization of decls.
3831 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3832 clang::NamedDecl* nVarDecl
3833 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3834 if (!nVarDecl) {
3835 Error("DeleteVariable", "Unknown variable %s", name);
3836 return 0;
3837 }
3838 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3839 if (!varDecl) {
3840 Error("DeleteVariable", "Entity %s is not a variable", name);
3841 return 0;
3842 }
3843
3844 clang::QualType qType = varDecl->getType();
3845 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3846 // Cannot set a reference's address to nullptr; the JIT can place it
3847 // into read-only memory (ROOT-7100).
3848 if (type->isPointerType()) {
3849 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3850 // set pointer to invalid.
3851 if (ppInt) *ppInt = nullptr;
3852 }
3853 return 1;
3854}
3855
3856////////////////////////////////////////////////////////////////////////////////
3857/// Save the current Cling state.
3858
3860{
3861#if defined(R__MUST_REVISIT)
3862#if R__MUST_REVISIT(6,2)
3864 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3865#endif
3866#endif
3867}
3868
3869////////////////////////////////////////////////////////////////////////////////
3870/// Save the current Cling state of global objects.
3871
3873{
3874#if defined(R__MUST_REVISIT)
3875#if R__MUST_REVISIT(6,2)
3877 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3878#endif
3879#endif
3880}
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// No op: see TClingCallbacks (used to update the list of globals)
3884
3886{
3887}
3888
3889////////////////////////////////////////////////////////////////////////////////
3890/// No op: see TClingCallbacks (used to update the list of global functions)
3891
3893{
3894}
3895
3896////////////////////////////////////////////////////////////////////////////////
3897/// No op: see TClingCallbacks (used to update the list of types)
3898
3900{
3901}
3902
3903////////////////////////////////////////////////////////////////////////////////
3904/// Check in what order the member of a tuple are layout.
3905enum class ETupleOrdering {
3906 kAscending,
3909};
3910
3912{
3915};
3916
3918{
3921};
3922
3924{
3925 std::tuple<int,double> value;
3928
3929 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3930 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3931
3932 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3933 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3934
3935 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3936 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3937
3938 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3940 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3942 } else {
3944 }
3945}
3946
3947static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3948{
3949 TClassEdit::TSplitType tupleContent(classname);
3950 std::string alternateName = "TEmulatedTuple";
3951 alternateName.append( classname + 5 );
3952
3953 std::string fullname = "ROOT::Internal::" + alternateName;
3954 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3955 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3956 return fullname;
3957
3958 std::string guard_name;
3959 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3960 std::ostringstream guard;
3961 guard << "ROOT_INTERNAL_TEmulated_";
3962 guard << guard_name;
3963
3964 std::ostringstream alternateTuple;
3965 alternateTuple << "#ifndef " << guard.str() << "\n";
3966 alternateTuple << "#define " << guard.str() << "\n";
3967 alternateTuple << "namespace ROOT { namespace Internal {\n";
3968 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3969 alternateTuple << "template <> struct " << alternateName << " {\n";
3970
3971 // This could also be a compile time choice ...
3972 switch(IsTupleAscending()) {
3974 unsigned int nMember = 0;
3975 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3976 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3977 while (iter != theEnd) {
3978 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3979 ++iter;
3980 ++nMember;
3981 }
3982 break;
3983 }
3985 unsigned int nMember = tupleContent.fElements.size() - 3;
3986 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3987 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3988 while (iter != theEnd) {
3989 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3990 ++iter;
3991 --nMember;
3992 }
3993 break;
3994 }
3996 Fatal("TCling::SetClassInfo::AlternateTuple",
3997 "Layout of std::tuple on this platform is unexpected.");
3998 break;
3999 }
4000 }
4001
4002 alternateTuple << "};\n";
4003 alternateTuple << "}}\n";
4004 alternateTuple << "#endif\n";
4005 if (!gCling->Declare(alternateTuple.str().c_str())) {
4006 Error("Load","Could not declare %s",alternateName.c_str());
4007 return "";
4008 }
4009 alternateName = "ROOT::Internal::" + alternateName;
4010 return alternateName;
4011}
4012
4013////////////////////////////////////////////////////////////////////////////////
4014/// Set pointer to the TClingClassInfo in TClass.
4015/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4016/// already have one.
4017
4019{
4020 // We are shutting down, there is no point in reloading, it only triggers
4021 // redundant deserializations.
4022 if (fIsShuttingDown) {
4023 // Remove the decl_id from the DeclIdToTClass map
4024 if (cl->fClassInfo) {
4026 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4027 // Test again as another thread may have set fClassInfo to nullptr.
4028 if (TClinginfo) {
4029 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4030 }
4031 delete TClinginfo;
4032 cl->fClassInfo = nullptr;
4033 }
4034 return;
4035 }
4036
4038 if (cl->fClassInfo && !reload) {
4039 return;
4040 }
4041 //Remove the decl_id from the DeclIdToTClass map
4042 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4043 if (TClinginfo) {
4044 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4045 }
4046 delete TClinginfo;
4047 cl->fClassInfo = nullptr;
4048 std::string name(cl->GetName());
4049
4050 auto SetWithoutClassInfoState = [](TClass *cl)
4051 {
4052 if (cl->fState != TClass::kHasTClassInit) {
4053 if (cl->fStreamerInfo->GetEntries() != 0) {
4055 } else {
4057 }
4058 }
4059 };
4060 // Handle the special case of 'tuple' where we ignore the real implementation
4061 // details and just overlay a 'simpler'/'simplistic' version that is easy
4062 // for the I/O to understand and handle.
4063 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4064 if (!reload)
4065 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
4066 if (reload || name.empty()) {
4067 // We could not generate the alternate
4068 SetWithoutClassInfoState(cl);
4069 return;
4070 }
4071 }
4072
4073 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4074 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4075 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4076 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4077 // TClingClassInfoReadOnly.
4078 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4079 if (!info->IsValid()) {
4080 SetWithoutClassInfoState(cl);
4081 delete info;
4082 return;
4083 }
4084 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4085 // In case a class contains an external enum, the enum will be seen as a
4086 // class. We must detect this special case and make the class a Zombie.
4087 // Here we assume that a class has at least one method.
4088 // We can NOT call TClass::Property from here, because this method
4089 // assumes that the TClass is well formed to do a lot of information
4090 // caching. The method SetClassInfo (i.e. here) is usually called during
4091 // the building phase of the TClass, hence it is NOT well formed yet.
4092 Bool_t zombieCandidate = kFALSE;
4093 if (
4094 info->IsValid() &&
4095 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4096 ) {
4097 zombieCandidate = kTRUE;
4098 }
4099 if (!info->IsLoaded()) {
4100 if (info->Property() & (kIsNamespace)) {
4101 // Namespaces can have info but no corresponding CINT dictionary
4102 // because they are auto-created if one of their contained
4103 // classes has a dictionary.
4104 zombieCandidate = kTRUE;
4105 }
4106 // this happens when no dictionary is available
4107 delete info;
4108 cl->fClassInfo = nullptr;
4109 }
4110 if (zombieCandidate && !cl->GetCollectionType()) {
4111 cl->MakeZombie();
4112 }
4113 // If we reach here, the info was valid (See early returns).
4114 if (cl->fState != TClass::kHasTClassInit) {
4115 if (cl->fClassInfo) {
4118 } else {
4119// if (TClassEdit::IsSTLCont(cl->GetName()) {
4120// There will be an emulated collection proxy, is that the same?
4121// cl->fState = TClass::kEmulated;
4122// } else {
4123 if (cl->fStreamerInfo->GetEntries() != 0) {
4125 } else {
4127 }
4128// }
4129 }
4130 }
4131 if (cl->fClassInfo) {
4132 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4133 }
4134}
4135
4136////////////////////////////////////////////////////////////////////////////////
4137/// Checks if an entity with the specified name is defined in Cling.
4138/// Returns kUnknown if the entity is not defined.
4139/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4140/// Returns kKnown if the entity is defined.
4141///
4142/// By default, structs, namespaces, classes, enums and unions are looked for.
4143/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4144/// namespaces only are considered. I.e. if the name is an enum or a union,
4145/// the returned value is false.
4146///
4147/// In the case where the class is not loaded and belongs to a namespace
4148/// or is nested, looking for the full class name is outputting a lots of
4149/// (expected) error messages. Currently the only way to avoid this is to
4150/// specifically check that each level of nesting is already loaded.
4151/// In case of templates the idea is that everything between the outer
4152/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4153
4155TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4156{
4158 static const char *anonEnum = "anonymous enum ";
4159 static const int cmplen = strlen(anonEnum);
4160
4161 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4162 return kUnknown;
4163 }
4164
4165 // Do not turn on the AutoLoading if it is globally off.
4166 autoload = autoload && IsClassAutoLoadingEnabled();
4167
4168 // Avoid the double search below in case the name is a fundamental type
4169 // or typedef to a fundamental type.
4170 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4171 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4172
4173 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4174 && fundType->GetType() > 0) {
4175 // Fundamental type, no a class.
4176 return kUnknown;
4177 }
4178
4179 // Migrated from within TClass::GetClass
4180 // If we want to know if a class or a namespace with this name exists in the
4181 // interpreter and this is an enum in the type system, before or after loading
4182 // according to the autoload function argument, return kUnknown.
4183 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4184 return kUnknown;
4185
4186 const char *classname = name;
4187
4188 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4189 class MaybeSuspendAutoLoadParse {
4190 int fStoreAutoLoad = 0;
4191 int fStoreAutoParse = 0;
4192 bool fSuspendedAutoParse = false;
4193 public:
4194 MaybeSuspendAutoLoadParse(int autoload) {
4195 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4196 }
4197
4198 void SuspendAutoParsing() {
4199 fSuspendedAutoParse = true;
4200 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4201 }
4202
4203 ~MaybeSuspendAutoLoadParse() {
4204 if (fSuspendedAutoParse)
4205 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4206 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4207 }
4208 };
4209
4210 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4211 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4212 autoLoadParseRAII.SuspendAutoParsing();
4213
4214 // First we want to check whether the decl exist, but _without_
4215 // generating any template instantiation. However, the lookup
4216 // still will create a forward declaration of the class template instance
4217 // if it exist. In this case, the return value of findScope will still
4218 // be zero but the type will be initialized.
4219 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4220 // this forward declaration.
4221 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4222 const clang::Type *type = nullptr;
4223 const clang::Decl *decl
4224 = lh.findScope(classname,
4225 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4226 : cling::LookupHelper::NoDiagnostics,
4227 &type, /* intantiateTemplate= */ false );
4228 if (!decl) {
4229 std::string buf = TClassEdit::InsertStd(classname);
4230 decl = lh.findScope(buf,
4231 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4232 : cling::LookupHelper::NoDiagnostics,
4233 &type,false);
4234 }
4235
4236 if (type) {
4237 // If decl==0 and the type is valid, then we have a forward declaration.
4238 if (!decl) {
4239 // If we have a forward declaration for a class template instantiation,
4240 // we want to ignore it if it was produced/induced by the call to
4241 // findScope, however we can not distinguish those from the
4242 // instantiation induce by 'soft' use (and thus also induce by the
4243 // same underlying code paths)
4244 // ['soft' use = use not requiring a complete definition]
4245 // So to reduce the amount of disruption to the existing code we
4246 // would just ignore those for STL collection, for which we really
4247 // need to have the compiled collection proxy (and thus the TClass
4248 // bootstrap).
4249 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4250 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4251 (type->getAsCXXRecordDecl());
4252 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4253 // Since the point of instantiation is invalid, we 'guess' that
4254 // the 'instantiation' of the forwarded type appended in
4255 // findscope.
4256 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4257 // For STL Collection we return kUnknown.
4258 return kUnknown;
4259 }
4260 }
4261 }
4263 if (!tci.IsValid()) {
4264 return kUnknown;
4265 }
4266 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4268
4269 if (tci.Property() & propertiesMask) {
4270 bool hasClassDefInline = false;
4271 if (isClassOrNamespaceOnly) {
4272 // We do not need to check for ClassDefInline when this is called from
4273 // TClass::Init, we only do it for the call from TClass::GetClass.
4274 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4275 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4276
4277 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4278 int lineNumber = 0;
4279 bool success = false;
4280 std::tie(success, lineNumber) =
4281 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4282 hasClassDefInline = success && (lineNumber == -1);
4283 }
4284 }
4285
4286 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4287 // , hasClassDefInline);
4288
4289 // We are now sure that the entry is not in fact an autoload entry.
4290 if (hasClassDefInline)
4291 return kWithClassDefInline;
4292 else
4293 return kKnown;
4294 } else {
4295 // We are now sure that the entry is not in fact an autoload entry.
4296 return kUnknown;
4297 }
4298 }
4299
4300 if (decl)
4301 return kKnown;
4302 else
4303 return kUnknown;
4304
4305 // Setting up iterator part of TClingTypedefInfo is too slow.
4306 // Copy the lookup code instead:
4307 /*
4308 TClingTypedefInfo t(fInterpreter, name);
4309 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4310 delete[] classname;
4311 return kTRUE;
4312 }
4313 */
4314
4315// const clang::Decl *decl = lh.findScope(name);
4316// if (!decl) {
4317// std::string buf = TClassEdit::InsertStd(name);
4318// decl = lh.findScope(buf);
4319// }
4320
4321// return (decl);
4322}
4323
4324////////////////////////////////////////////////////////////////////////////////
4325/// Return true if there is a class template by the given name ...
4326
4328{
4329 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4330 // Interpreter transaction ahead, needs locking
4332 const clang::Decl *decl
4333 = lh.findClassTemplate(name,
4334 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4335 : cling::LookupHelper::NoDiagnostics);
4336 if (!decl) {
4337 std::string strname = "std::";
4338 strname += name;
4339 decl = lh.findClassTemplate(strname,
4340 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4341 : cling::LookupHelper::NoDiagnostics);
4342 }
4343 return nullptr != decl;
4344}
4345
4346////////////////////////////////////////////////////////////////////////////////
4347/// Create list of pointers to base class(es) for TClass cl.
4348
4350{
4352 if (cl->fBase) {
4353 return;
4354 }
4356 if (!tci) return;
4358 TList *listOfBase = new TList;
4359 while (t.Next()) {
4360 // if name cannot be obtained no use to put in list
4361 if (t.IsValid() && t.Name()) {
4363 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4364 }
4365 }
4366 // Now that is complete, publish it.
4367 cl->fBase = listOfBase;
4368}
4369
4370////////////////////////////////////////////////////////////////////////////////
4371/// Create list of pointers to enums for TClass cl.
4372
4373void TCling::LoadEnums(TListOfEnums& enumList) const
4374{
4376
4377 const Decl * D;
4378 TClass* cl = enumList.GetClass();
4379 if (cl) {
4380 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4381 }
4382 else {
4383 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4384 }
4385 // Iterate on the decl of the class and get the enums.
4386 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4387 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4388 // Collect all contexts of the namespace.
4389 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4390 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4391 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4392 declIter != declEnd; ++declIter) {
4393 // Iterate on all decls for each context.
4394 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4395 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4396 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4397 // Get name of the enum type.
4398 std::string buf;
4399 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4400 llvm::raw_string_ostream stream(buf);
4401 // Don't trigger fopen of the source file to count lines:
4402 Policy.AnonymousTagLocations = false;
4403 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4404 stream.flush();
4405 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4406 if (!buf.empty()) {
4407 const char* name = buf.c_str();
4408 // Add the enum to the list of loaded enums.
4409 enumList.Get(ED, name);
4410 }
4411 }
4412 }
4413 }
4414 }
4415}
4416
4417////////////////////////////////////////////////////////////////////////////////
4418/// Create list of pointers to function templates for TClass cl.
4419
4421{
4423
4424 const Decl * D;
4425 TListOfFunctionTemplates* funcTempList;
4426 if (cl) {
4427 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4428 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4429 }
4430 else {
4431 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4432 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4433 }
4434 // Iterate on the decl of the class and get the enums.
4435 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4436 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4437 // Collect all contexts of the namespace.
4438 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4439 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4440 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4441 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4442 // Iterate on all decls for each context.
4443 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4444 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4445 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4446 funcTempList->Get(FTD);
4447 }
4448 }
4449 }
4450 }
4451}
4452
4453////////////////////////////////////////////////////////////////////////////////
4454/// Get the scopes representing using declarations of namespace
4455
4456std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4457{
4459 return ci->GetUsingNamespaces();
4460}
4461
4462////////////////////////////////////////////////////////////////////////////////
4463/// Create list of pointers to data members for TClass cl.
4464/// This is now a nop. The creation and updating is handled in
4465/// TListOfDataMembers.
4466
4468{
4469}
4470
4471////////////////////////////////////////////////////////////////////////////////
4472/// Create list of pointers to methods for TClass cl.
4473/// This is now a nop. The creation and updating is handled in
4474/// TListOfFunctions.
4475
4477{
4478}
4479
4480////////////////////////////////////////////////////////////////////////////////
4481/// Update the list of pointers to method for TClass cl
4482/// This is now a nop. The creation and updating is handled in
4483/// TListOfFunctions.
4484
4486{
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Update the list of pointers to data members for TClass cl
4491/// This is now a nop. The creation and updating is handled in
4492/// TListOfDataMembers.
4493
4495{
4496}
4497
4498////////////////////////////////////////////////////////////////////////////////
4499/// Create list of pointers to method arguments for TMethod m.
4500
4502{
4504 if (m->fMethodArgs) {
4505 return;
4506 }
4507 TList *arglist = new TList;
4509 while (t.Next()) {
4510 if (t.IsValid()) {
4512 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4513 }
4514 }
4515 m->fMethodArgs = arglist;
4516}
4517
4518////////////////////////////////////////////////////////////////////////////////
4519/// Return whether we are waiting for more input either because the collected
4520/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4521
4523{
4524 return fMetaProcessor->awaitingMoreInput();
4525}
4526
4527////////////////////////////////////////////////////////////////////////////////
4528/// Generate a TClass for the given class.
4529/// Since the caller has already check the ClassInfo, let it give use the
4530/// result (via the value of emulation) rather than recalculate it.
4531
4532TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4533{
4534// For now the following line would lead to the (unwanted) instantiation
4535// of class template. This could/would need to be resurrected only if
4536// we re-introduce so sort of automatic instantiation. However this would
4537// have to include carefull look at the template parameter to avoid
4538// creating instance we can not really use (if the parameter are only forward
4539// declaration or do not have all the necessary interfaces).
4540
4541 // TClingClassInfo tci(fInterpreter, classname);
4542 // if (1 || !tci.IsValid()) {
4543
4544 Version_t version = 1;
4545 if (TClassEdit::IsSTLCont(classname)) {
4546 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4547 }
4549 TClass *cl = new TClass(classname, version, silent);
4550 if (emulation) {
4552 } else {
4553 // Set the class version if the class is versioned.
4554 // Note that we cannot just call CLASS::Class_Version() as we might not have
4555 // an execution engine (when invoked from rootcling).
4556
4557 // Do not call cl->GetClassVersion(), it has side effects!
4558 Version_t oldvers = cl->fClassVersion;
4559 if (oldvers == version && cl->GetClassInfo()) {
4560 // We have a version and it might need an update.
4562 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4563 // Namespaces don't have class versions.
4564 return cl;
4565 }
4566 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4569 if (!mi.IsValid()) {
4570 if (cl->TestBit(TClass::kIsTObject)) {
4571 Error("GenerateTClass",
4572 "Cannot find %s::Class_Version()! Class version might be wrong.",
4573 cl->GetName());
4574 }
4575 return cl;
4576 }
4577 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4578 *fInterpreter);
4579 if (newvers == -1) {
4580 // Didn't manage to determine the class version from the AST.
4581 // Use runtime instead.
4582 if ((mi.Property() & kIsStatic)
4583 && !fInterpreter->isInSyntaxOnlyMode()) {
4584 // This better be a static function.
4586 callfunc.SetFunc(&mi);
4587 newvers = callfunc.ExecInt(nullptr);
4588 } else {
4589 Error("GenerateTClass",
4590 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4591 cl->GetName());
4592 }
4593 }
4594 if (newvers != oldvers) {
4595 cl->fClassVersion = newvers;
4596 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4597 }
4598 }
4599 }
4600
4601 return cl;
4602
4603// } else {
4604// return GenerateTClass(&tci,silent);
4605// }
4606}
4607
4608#if 0
4609////////////////////////////////////////////////////////////////////////////////
4610
4611static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4612{
4613 includes += info->FileName();
4614
4615 const clang::ClassTemplateSpecializationDecl *templateCl
4616 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4617 if (templateCl) {
4618 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4619 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4620 if (arg.getKind() == clang::TemplateArgument::Type) {
4621 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4622
4623 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4624 // We really need a header file.
4625 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4626 if (argdecl) {
4627 includes += ";";
4628 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4629 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4630 } else {
4631 std::string Result;
4632 llvm::raw_string_ostream OS(Result);
4633 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4634 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4635 }
4636 }
4637 }
4638 }
4639 }
4640}
4641#endif
4642
4643////////////////////////////////////////////////////////////////////////////////
4644/// Generate a TClass for the given class.
4645
4646TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4647{
4648 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4649 if (!info || !info->IsValid()) {
4650 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4651 return nullptr;
4652 }
4653 // We are in the case where we have AST nodes for this class.
4654 TClass *cl = nullptr;
4655 std::string classname;
4656 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4657 if (TClassEdit::IsSTLCont(classname)) {
4658#if 0
4659 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4660 // We need to build up the list of required headers, by
4661 // looking at each template arguments.
4662 TString includes;
4663 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4664
4665 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4666 // 0 means success.
4667 cl = TClass::LoadClass(classnam.c_str(), silent);
4668 if (cl == 0) {
4669 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4670 }
4671 }
4672#endif
4673 if (cl == nullptr) {
4674 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4675 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4677 }
4678 } else {
4679 // For regular class, just create a TClass on the fly ...
4680 // Not quite useful yet, but that what CINT used to do anyway.
4681 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4682 }
4683 // Add the new TClass to the map of declid and TClass*.
4684 if (cl) {
4686 }
4687 return cl;
4688}
4689
4690////////////////////////////////////////////////////////////////////////////////
4691/// Generate the dictionary for the C++ classes listed in the first
4692/// argument (in a semi-colon separated list).
4693/// 'includes' contains a semi-colon separated list of file to
4694/// `#include` in the dictionary.
4695/// For example:
4696/// ~~~ {.cpp}
4697/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4698/// ~~~
4699/// or
4700/// ~~~ {.cpp}
4701/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4702/// ~~~
4703
4704Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4705{
4706 if (classes == nullptr || classes[0] == 0) {
4707 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4708 return 0;
4709 }
4710 // Split the input list
4711 std::vector<std::string> listClasses;
4712 for (
4713 const char* current = classes, *prev = classes;
4714 *current != 0;
4715 ++current
4716 ) {
4717 if (*current == ';') {
4718 listClasses.push_back(std::string(prev, current - prev));
4719 prev = current + 1;
4720 }
4721 else if (*(current + 1) == 0) {
4722 listClasses.push_back(std::string(prev, current + 1 - prev));
4723 prev = current + 1;
4724 }
4725 }
4726 std::vector<std::string> listIncludes;
4727 if (!includes)
4728 includes = "";
4729 for (
4730 const char* current = includes, *prev = includes;
4731 *current != 0;
4732 ++current
4733 ) {
4734 if (*current == ';') {
4735 listIncludes.push_back(std::string(prev, current - prev));
4736 prev = current + 1;
4737 }
4738 else if (*(current + 1) == 0) {
4739 listIncludes.push_back(std::string(prev, current + 1 - prev));
4740 prev = current + 1;
4741 }
4742 }
4743 // Generate the temporary dictionary file
4744 return !TCling_GenerateDictionary(listClasses, listIncludes,
4745 std::vector<std::string>(), std::vector<std::string>());
4746}
4747
4748////////////////////////////////////////////////////////////////////////////////
4749/// Return pointer to cling Decl of global/static variable that is located
4750/// at the address given by addr.
4751
4752TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4753{
4755 DeclId_t d;
4756 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4757
4758 // Could trigger deserialization of decls.
4759 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4760
4761 if (cl) {
4762 d = cl->GetDataMember(name);
4763 // We check if the decl of the data member has an annotation which indicates
4764 // an ioname.
4765 // In case this is true, if the name requested is not the ioname, we
4766 // return 0, as if the member did not exist. In some sense we override
4767 // the information in the TClassInfo instance, isolating the typesystem in
4768 // TClass from the one in the AST.
4769 if (const ValueDecl* decl = (const ValueDecl*) d){
4770 std::string ioName;
4771 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4772 if (hasIoName && ioName != name) return nullptr;
4773 }
4774 return d;
4775 }
4776 // We are looking up for something on the TU scope.
4777 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4778 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4779 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4780 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4781 // are only fulfilling ROOT's understanding for a Data Member.
4782 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4783 // similar as below.
4784 using namespace clang;
4785 Sema& SemaR = fInterpreter->getSema();
4786 DeclarationName DName = &SemaR.Context.Idents.get(name);
4787
4788 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4789 Sema::ForExternalRedeclaration);
4790
4791 cling::utils::Lookup::Named(&SemaR, R);
4792
4793 LookupResult::Filter F = R.makeFilter();
4794 // Filter the data-member looking decls.
4795 while (F.hasNext()) {
4796 NamedDecl *D = F.next();
4797 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4798 isa<IndirectFieldDecl>(D))
4799 continue;
4800 F.erase();
4801 }
4802 F.done();
4803
4804 if (R.isSingleResult())
4805 return R.getFoundDecl();
4806 return nullptr;
4807}
4808
4809////////////////////////////////////////////////////////////////////////////////
4810/// Return pointer to cling Decl of global/static variable that is located
4811/// at the address given by addr.
4812
4814{
4816
4817 const clang::Decl* possibleEnum = nullptr;
4818 // FInd the context of the decl.
4819 if (cl) {
4821 if (cci) {
4822 const clang::DeclContext* dc = nullptr;
4823 if (const clang::Decl* D = cci->GetDecl()) {
4824 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4825 dc = dyn_cast<clang::RecordDecl>(D);
4826 }
4827 }
4828 if (dc) {
4829 // If it is a data member enum.
4830 // Could trigger deserialization of decls.
4831 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4832 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4833 } else {
4834 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4835 }
4836 }
4837 } else {
4838 // If it is a global enum.
4839 // Could trigger deserialization of decls.
4840 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4841 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4842 }
4843 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4844 && isa<clang::EnumDecl>(possibleEnum)) {
4845 return possibleEnum;
4846 }
4847 return nullptr;
4848}
4849
4850////////////////////////////////////////////////////////////////////////////////
4851/// Return pointer to cling DeclId for a global value
4852
4853TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4854{
4855 if (!gv) return nullptr;
4856
4857 llvm::StringRef mangled_name = gv->getName();
4858
4859 int err = 0;
4860 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4861 if (err) {
4862 if (err == -2) {
4863 // It might simply be an unmangled global name.
4864 DeclId_t d;
4866 d = gcl.GetDataMember(mangled_name.str().c_str());
4867 return d;
4868 }
4869 return nullptr;
4870 }
4871
4872 std::string scopename(demangled_name_c);
4873 free(demangled_name_c);
4874
4875 //
4876 // Separate out the class or namespace part of the
4877 // function name.
4878 //
4879 std::string dataname;
4880
4881 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4882 scopename.erase(0, sizeof("typeinfo for ")-1);
4883 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4884 scopename.erase(0, sizeof("vtable for ")-1);
4885 } else {
4886 // See if it is a function
4887 std::string::size_type pos = scopename.rfind('(');
4888 if (pos != std::string::npos) {
4889 return nullptr;
4890 }
4891 // Separate the scope and member name
4892 pos = scopename.rfind(':');
4893 if (pos != std::string::npos) {
4894 if ((pos != 0) && (scopename[pos-1] == ':')) {
4895 dataname = scopename.substr(pos+1);
4896 scopename.erase(pos-1);
4897 }
4898 } else {
4899 scopename.clear();
4900 dataname = scopename;
4901 }
4902 }
4903 //fprintf(stderr, "name: '%s'\n", name.c_str());
4904 // Now we have the class or namespace name, so do the lookup.
4905
4906
4907 DeclId_t d;
4908 if (scopename.size()) {
4909 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4910 d = cl.GetDataMember(dataname.c_str());
4911 }
4912 else {
4914 d = gcl.GetDataMember(dataname.c_str());
4915 }
4916 return d;
4917}
4918
4919////////////////////////////////////////////////////////////////////////////////
4920/// NOT IMPLEMENTED.
4921
4923{
4924 Error("GetDataMemberWithValue()", "not implemented");
4925 return nullptr;
4926}
4927
4928////////////////////////////////////////////////////////////////////////////////
4929/// Return pointer to cling DeclId for a data member with a given name.
4930
4932{
4933 // NOT IMPLEMENTED.
4934 Error("GetDataMemberAtAddr()", "not implemented");
4935 return nullptr;
4936}
4937
4938////////////////////////////////////////////////////////////////////////////////
4939/// Return the cling mangled name for a method of a class with parameters
4940/// params (params is a string of actual arguments, not formal ones). If the
4941/// class is 0 the global function list will be searched.
4942
4943TString TCling::GetMangledName(TClass* cl, const char* method,
4944 const char* params, Bool_t objectIsConst /* = kFALSE */)
4945{
4948 if (cl) {
4950 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4951 &offset);
4952 }
4953 else {
4956 func.SetFunc(&gcl, method, params, &offset);
4957 }
4959 if (!mi) return "";
4960 TString mangled_name( mi->GetMangledName() );
4961 delete mi;
4962 return mangled_name;
4963}
4964
4965////////////////////////////////////////////////////////////////////////////////
4966/// Return the cling mangled name for a method of a class with a certain
4967/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4968/// list will be searched.
4969
4971 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4972 EFunctionMatchMode mode /* = kConversionMatch */)
4973{
4975 if (cl) {
4976 return ((TClingClassInfo*)cl->GetClassInfo())->
4977 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4978 }
4980 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4981}
4982
4983////////////////////////////////////////////////////////////////////////////////
4984/// Return pointer to cling interface function for a method of a class with
4985/// parameters params (params is a string of actual arguments, not formal
4986/// ones). If the class is 0 the global function list will be searched.
4987
4988void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4989 const char* params, Bool_t objectIsConst /* = kFALSE */)
4990{
4993 if (cl) {
4995 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4996 &offset);
4997 }
4998 else {
5001 func.SetFunc(&gcl, method, params, &offset);
5002 }
5003 return (void*) func.InterfaceMethod();
5004}
5005
5006////////////////////////////////////////////////////////////////////////////////
5007/// Return pointer to cling interface function for a method of a class with
5008/// a certain name.
5009
5010TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5011{
5013 DeclId_t f;
5014 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5015 if (cl) {
5016 f = cl->GetMethod(method).GetDeclId();
5017 }
5018 else {
5020 f = gcl.GetMethod(method).GetDeclId();
5021 }
5022 return f;
5023
5024}
5025
5026////////////////////////////////////////////////////////////////////////////////
5027/// Insert overloads of name in cl to res.
5028
5029void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5030 std::vector<DeclId_t>& res) const
5031{
5032 clang::Sema& S = fInterpreter->getSema();
5033 clang::ASTContext& Ctx = S.Context;
5034 const clang::Decl* CtxDecl
5035 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5036 Ctx.getTranslationUnitDecl();
5037 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5038 const clang::DeclContext* DeclCtx = RecDecl;
5039
5040 if (!DeclCtx)
5041 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5042 if (!DeclCtx) return;
5043
5044 clang::DeclarationName DName;
5045 // The DeclarationName is funcname, unless it's a ctor or dtor.
5046 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5047
5048 if (RecDecl) {
5049 if (RecDecl->getNameAsString() == funcname) {
5050 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5051 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5052 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5053 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5054 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5055 } else {
5056 DName = &Ctx.Idents.get(funcname);
5057 }
5058 } else {
5059 DName = &Ctx.Idents.get(funcname);
5060 }
5061
5062 // NotForRedeclaration: we want to find names in inline namespaces etc.
5063 clang::LookupResult R(S, DName, clang::SourceLocation(),
5064 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5065 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5066 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5067 if (R.empty()) return;
5068 R.resolveKind();
5069 res.reserve(res.size() + (R.end() - R.begin()));
5070 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5071 IR != ER; ++IR) {
5072 if (const clang::FunctionDecl* FD
5073 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5074 if (!FD->getDescribedFunctionTemplate()) {
5075 res.push_back(FD);
5076 }
5077 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5078 // FIXME: multi-level using
5079 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5080 res.push_back(USD);
5081 }
5082 }
5083 }
5084}
5085
5086////////////////////////////////////////////////////////////////////////////////
5087/// Return pointer to cling interface function for a method of a class with
5088/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5089/// function list will be searched.
5090
5092 const char* proto,
5093 Bool_t objectIsConst /* = kFALSE */,
5094 EFunctionMatchMode mode /* = kConversionMatch */)
5095{
5097 void* f;
5098 if (cl) {
5099 f = ((TClingClassInfo*)cl->GetClassInfo())->
5100 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5101 }
5102 else {
5104 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5105 }
5106 return f;
5107}
5108
5109////////////////////////////////////////////////////////////////////////////////
5110/// Return pointer to cling DeclId for a method of a class with
5111/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5112/// function list will be searched.
5113
5114TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5115 const char* params,
5116 Bool_t objectIsConst /* = kFALSE */)
5117{
5119 DeclId_t f;
5120 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5121 if (cl) {
5122 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5123 }
5124 else {
5126 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5127 }
5128 return f;
5129}
5130
5131////////////////////////////////////////////////////////////////////////////////
5132/// Return pointer to cling interface function for a method of a class with
5133/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5134/// function list will be searched.
5135
5136TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5137 const char* proto,
5138 Bool_t objectIsConst /* = kFALSE */,
5139 EFunctionMatchMode mode /* = kConversionMatch */)
5140{
5142 DeclId_t f;
5143 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5144 if (cl) {
5145 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5146 }
5147 else {
5149 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5150 }
5151 return f;
5152}
5153
5154////////////////////////////////////////////////////////////////////////////////
5155/// Return pointer to cling interface function for a method of a class with
5156/// a certain name.
5157
5158TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5159{
5161 DeclId_t f;
5162 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5163 if (cl) {
5164 f = cl->GetFunctionTemplate(name);
5165 }
5166 else {
5168 f = gcl.GetFunctionTemplate(name);
5169 }
5170 return f;
5171
5172}
5173
5174////////////////////////////////////////////////////////////////////////////////
5175/// The 'name' is known to the interpreter, this function returns
5176/// the internal version of this name (usually just resolving typedefs)
5177/// This is used in particular to synchronize between the name used
5178/// by rootcling and by the run-time environment (TClass)
5179/// Return 0 if the name is not known.
5180
5181void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5182{
5183 output.clear();
5184
5186
5188 if (!cl.IsValid()) {
5189 return ;
5190 }
5191 if (full) {
5193 return;
5194 }
5195 // Well well well, for backward compatibility we need to act a bit too
5196 // much like CINT.
5199
5200 return;
5201}
5202
5203////////////////////////////////////////////////////////////////////////////////
5204/// Execute a global function with arguments params.
5205///
5206/// FIXME: The cint-based version of this code does not check if the
5207/// SetFunc() call works, and does not do any real checking
5208/// for errors from the Exec() call. It did fetch the most
5209/// recent cint security error and return that in error, but
5210/// this does not really translate well to cling/clang. We
5211/// should enhance these interfaces so that we can report
5212/// compilation and runtime errors properly.
5213
5214void TCling::Execute(const char* function, const char* params, int* error)
5215{
5217 if (error) {
5218 *error = TInterpreter::kNoError;
5219 }
5221 Longptr_t offset = 0L;
5223 func.SetFunc(&cl, function, params, &offset);
5224 func.Exec(nullptr);
5225}
5226
5227////////////////////////////////////////////////////////////////////////////////
5228/// Execute a method from class cl with arguments params.
5229///
5230/// FIXME: The cint-based version of this code does not check if the
5231/// SetFunc() call works, and does not do any real checking
5232/// for errors from the Exec() call. It did fetch the most
5233/// recent cint security error and return that in error, but
5234/// this does not really translate well to cling/clang. We
5235/// should enhance these interfaces so that we can report
5236/// compilation and runtime errors properly.
5237
5238void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5239 const char* params, Bool_t objectIsConst, int* error)
5240{
5242 if (error) {
5243 *error = TInterpreter::kNoError;
5244 }
5245 // If the actual class of this object inherits 2nd (or more) from TObject,
5246 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5247 // hence gInterpreter->Execute will improperly correct the offset.
5248 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5249 Longptr_t offset = 0L;
5251 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5252 void* address = (void*)((Longptr_t)addr + offset);
5253 func.Exec(address);
5254}
5255
5256////////////////////////////////////////////////////////////////////////////////
5257
5258void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5259 const char* params, int* error)
5260{
5261 Execute(obj,cl,method,params,false,error);
5262}
5263
5264////////////////////////////////////////////////////////////////////////////////
5265/// Execute a method from class cl with the arguments in array params
5266/// (params[0] ... params[n] = array of TObjString parameters).
5267/// Convert the TObjArray array of TObjString parameters to a character
5268/// string of comma separated parameters.
5269/// The parameters of type 'char' are enclosed in double quotes and all
5270/// internal quotes are escaped.
5271
5272void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5273 TObjArray* params, int* error)
5274{
5275 if (!method) {
5276 Error("Execute", "No method was defined");
5277 return;
5278 }
5279 TList* argList = method->GetListOfMethodArgs();
5280 // Check number of actual parameters against of expected formal ones
5281
5282 Int_t nparms = argList->LastIndex() + 1;
5283 Int_t argc = params ? params->GetEntries() : 0;
5284
5285 if (argc > nparms) {
5286 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5287 return;
5288 }
5289 if (nparms != argc) {
5290 // Let's see if the 'missing' argument are all defaulted.
5291 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5292 assert(nparms > 0);
5293
5294 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5295 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5296 // There is a default value for the first missing
5297 // argument, so we are fine.
5298 } else {
5299 Int_t firstDefault = -1;
5300 for (Int_t i = 0; i < nparms; i ++) {
5301 arg = (TMethodArg *) argList->At( i );
5302 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5303 firstDefault = i;
5304 break;
5305 }
5306 }
5307 if (firstDefault >= 0) {
5308 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);
5309 } else {
5310 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5311 }
5312 return;
5313 }
5314 }
5315
5316 const char* listpar = "";
5317 TString complete(10);
5318 if (params) {
5319 // Create a character string of parameters from TObjArray
5320 TIter next(params);
5321 for (Int_t i = 0; i < argc; i ++) {
5322 TMethodArg* arg = (TMethodArg*) argList->At(i);
5324 TObjString* nxtpar = (TObjString*) next();
5325 if (i) {
5326 complete += ',';
5327 }
5328 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5329 TString chpar('\"');
5330 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5331 // At this point we have to check if string contains \\"
5332 // and apply some more sophisticated parser. Not implemented yet!
5333 complete += chpar;
5334 complete += '\"';
5335 }
5336 else {
5337 complete += nxtpar->String();
5338 }
5339 }
5340 listpar = complete.Data();
5341 }
5342
5343 // And now execute it.
5345 if (error) {
5346 *error = TInterpreter::kNoError;
5347 }
5348 // If the actual class of this object inherits 2nd (or more) from TObject,
5349 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5350 // hence gInterpreter->Execute will improperly correct the offset.
5351 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5353 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5354 func.Init(*minfo);
5355 func.SetArgs(listpar);
5356 // Now calculate the 'this' pointer offset for the method
5357 // when starting from the class described by cl.
5358 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5359 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5360 void* address = (void*)((Longptr_t)addr + offset);
5361 func.Exec(address);
5362}
5363
5364////////////////////////////////////////////////////////////////////////////////
5365
5366void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5367 const void* args[] /*=0*/,
5368 int nargs /*=0*/,
5369 void* ret/*= 0*/) const
5370{
5371 if (!method) {
5372 Error("ExecuteWithArgsAndReturn", "No method was defined");
5373 return;
5374 }
5375
5376 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5377 TClingCallFunc func(*minfo);
5378 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5379}
5380
5381////////////////////////////////////////////////////////////////////////////////
5382/// Execute a cling macro.
5383
5385{
5387 fCurExecutingMacros.push_back(filename);
5389 fCurExecutingMacros.pop_back();
5390 return result;
5391}
5392
5393////////////////////////////////////////////////////////////////////////////////
5394/// Return the file name of the current un-included interpreted file.
5395/// See the documentation for GetCurrentMacroName().
5396
5398{
5399 Warning("GetTopLevelMacroName", "Must change return type!");
5400 return fCurExecutingMacros.back();
5401}
5402
5403////////////////////////////////////////////////////////////////////////////////
5404/// Return the file name of the currently interpreted file,
5405/// included or not. Example to illustrate the difference between
5406/// GetCurrentMacroName() and GetTopLevelMacroName():
5407/// ~~~ {.cpp}
5408/// void inclfile() {
5409/// std::cout << "In inclfile.C" << std::endl;
5410/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5411/// TCling::GetCurrentMacroName() << std::endl;
5412/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5413/// TCling::GetTopLevelMacroName() << std::endl;
5414/// }
5415/// ~~~
5416/// ~~~ {.cpp}
5417/// void mymacro() {
5418/// std::cout << "In mymacro.C" << std::endl;
5419/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5420/// TCling::GetCurrentMacroName() << std::endl;
5421/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5422/// TCling::GetTopLevelMacroName() << std::endl;
5423/// std::cout << " Now calling inclfile..." << std::endl;
5424/// gInterpreter->ProcessLine(".x inclfile.C");;
5425/// }
5426/// ~~~
5427/// Running mymacro.C will print:
5428///
5429/// ~~~ {.cpp}
5430/// root [0] .x mymacro.C
5431/// ~~~
5432/// In mymacro.C
5433/// ~~~ {.cpp}
5434/// TCling::GetCurrentMacroName() returns ./mymacro.C
5435/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5436/// ~~~
5437/// Now calling inclfile...
5438/// In inclfile.h
5439/// ~~~ {.cpp}
5440/// TCling::GetCurrentMacroName() returns inclfile.C
5441/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5442/// ~~~
5443
5445{
5446#if defined(R__MUST_REVISIT)
5447#if R__MUST_REVISIT(6,0)
5448 Warning("GetCurrentMacroName", "Must change return type!");
5449#endif
5450#endif
5451 return fCurExecutingMacros.back();
5452}
5453
5454////////////////////////////////////////////////////////////////////////////////
5455/// Return the absolute type of typeDesc.
5456/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5457/// You need to use the result immediately before it is being overwritten.
5458
5459const char* TCling::TypeName(const char* typeDesc)
5460{
5461 TTHREAD_TLS_DECL(std::string,t);
5462
5463 if (!strstr(typeDesc, "(*)(")) {
5464 const char *s = strchr(typeDesc, ' ');
5465 const char *template_start = strchr(typeDesc, '<');
5466 if (!strcmp(typeDesc, "long long")) {
5467 t = typeDesc;
5468 }
5469 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5470 t = typeDesc;
5471 }
5472 // s is the position of the second 'word' (if any)
5473 // except in the case of templates where there will be a space
5474 // just before any closing '>': eg.
5475 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5476 else if (s && (template_start == nullptr || (s < template_start))) {
5477 t = s + 1;
5478 }
5479 else {
5480 t = typeDesc;
5481 }
5482 }
5483 else {
5484 t = typeDesc;
5485 }
5486 auto l = t.length();
5487 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5488 --l;
5489 t.resize(l);
5490 return t.c_str(); // NOLINT
5491}
5492
5493static bool requiresRootMap(const char* rootmapfile)
5494{
5495 assert(rootmapfile && *rootmapfile);
5496
5497 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5498 libName.consume_back(".rootmap");
5499
5500 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5501}
5502
5503////////////////////////////////////////////////////////////////////////////////
5504/// Read and parse a rootmapfile in its new format, and return 0 in case of
5505/// success, -1 if the file has already been read, and -3 in case its format
5506/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5507/// error.
5508
5509int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5510{
5511 if (!(rootmapfile && *rootmapfile))
5512 return 0;
5513
5514 if (!requiresRootMap(rootmapfile))
5515 return 0; // success
5516
5517 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5518 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5519
5520 std::string rootmapfileNoBackslash(rootmapfile);
5521#ifdef _MSC_VER
5522 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5523#endif
5524 // Add content of a specific rootmap file
5525 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5526 return -1;
5527
5528 // Line 1 is `{ decls }`
5529 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5530
5531 std::ifstream file(rootmapfileNoBackslash);
5532 std::string line;
5533 line.reserve(200);
5534 std::string lib_name;
5535 line.reserve(100);
5536 bool newFormat = false;
5537 while (getline(file, line, '\n')) {
5538 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5539 file.close();
5540 return -3; // old format
5541 }
5542 newFormat = true;
5543
5544 if (line.compare(0, 9, "{ decls }") == 0) {
5545 // forward declarations
5546
5547 while (getline(file, line, '\n')) {
5548 if (line[0] == '[')
5549 break;
5550 if (!uniqueString) {
5551 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5552 rootmapfileNoBackslash.c_str());
5553 return -4;
5554 }
5555 if (!lineDirective.empty())
5556 uniqueString->Append(lineDirective);
5557 uniqueString->Append(line + '\n');
5558 }
5559 }
5560 const char firstChar = line[0];
5561 if (firstChar == '[') {
5562 // new section (library)
5563 auto brpos = line.find(']');
5564 if (brpos == string::npos)
5565 continue;
5566 lib_name = line.substr(1, brpos - 1);
5567 // Remove spaces at the beginning and at the end of the library name
5568 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5569 lib_name.erase(0, lib_name.find_first_not_of(' '));
5570 if (gDebug > 3) {
5571 TString lib_nameTstr(lib_name.c_str());
5572 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5573 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5574 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5575 if (wlib) {
5576 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5577 } else {
5578 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5579 }
5580 delete[] wlib;
5581 delete tokens;
5582 }
5583 } else {
5584 auto keyLenIt = keyLenMap.find(firstChar);
5585 if (keyLenIt == keyLenMap.end())
5586 continue;
5587 unsigned int keyLen = keyLenIt->second;
5588 // Do not make a copy, just start after the key
5589 const char *keyname = line.c_str() + keyLen;
5590 if (gDebug > 6)
5591 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5592 TEnvRec *isThere = fMapfile->Lookup(keyname);
5593 if (isThere) {
5594 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5595 if (firstChar == 'n') {
5596 if (gDebug > 3)
5597 Info("ReadRootmapFile",
5598 "While processing %s, namespace %s was found to be associated to %s although it is already "
5599 "associated to %s",
5600 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5601 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5602 lib_name += " ";
5603 lib_name += isThere->GetValue();
5604 fMapfile->SetValue(keyname, lib_name.c_str());
5605 } else if (!TClassEdit::IsSTLCont(keyname)) {
5606 Warning("ReadRootmapFile",
5607 "While processing %s, %s %s was found to be associated to %s although it is already "
5608 "associated to %s",
5609 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5610 isThere->GetValue());
5611 }
5612 } else { // the same key for the same lib
5613 if (gDebug > 3)
5614 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5615 rootmapfile, keyname, lib_name.c_str());
5616 }
5617 } else {
5618 fMapfile->SetValue(keyname, lib_name.c_str());
5619 }
5620 }
5621 }
5622 file.close();
5623 return 0;
5624}
5625
5626////////////////////////////////////////////////////////////////////////////////
5627/// Create a resource table and read the (possibly) three resource files,
5628/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5629/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5630/// can read additional user defined resource files by creating additional TEnv
5631/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5632/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5633/// case the home directory resides on an automounted remote file system
5634/// and one wants to avoid the file system from being mounted.
5635
5637{
5638 assert(requiresRootMap(name) && "We have a module!");
5639
5640 if (!requiresRootMap(name))
5641 return;
5642
5644
5646
5647 TString sname = "system";
5648 sname += name;
5649 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5650
5651 Int_t ret = ReadRootmapFile(s);
5652 if (ret == -3) // old format
5654 delete [] s;
5655 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5657 ret = ReadRootmapFile(s);
5658 if (ret == -3) // old format
5660 delete [] s;
5661 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5662 ret = ReadRootmapFile(name);
5663 if (ret == -3) // old format
5665 }
5666 } else {
5667 ret = ReadRootmapFile(name);
5668 if (ret == -3) // old format
5670 }
5671 fMapfile->IgnoreDuplicates(ignore);
5672}
5673
5674
5675namespace {
5676 using namespace clang;
5677
5678 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5679 // This class is to be considered an helper for AutoLoading.
5680 // It is a recursive visitor is used to inspect namespaces and specializations
5681 // coming from forward declarations in rootmaps and to set the external visible
5682 // storage flag for them.
5683 public:
5684 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5685 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5686 // We want to enable the external lookup for this namespace
5687 // because it may shadow the lookup of other names contained
5688 // in that namespace
5689
5690 nsDecl->setHasExternalVisibleStorage();
5691 fNSSet.insert(nsDecl);
5692 return true;
5693 }
5694 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5695 // We want to enable the external lookup for this specialization
5696 // because we can provide a definition for it!
5697 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5698 //SpecSet.insert(specDecl);
5699 specDecl->setHasExternalLexicalStorage();
5700
5701 // No need to recurse. On the contrary, recursing is actively harmful:
5702 // NOTE: must not recurse to prevent this visitor from triggering loading from
5703 // the external AST source (i.e. autoloading). This would be triggered right here,
5704 // before autoloading is even set up, as rootmap file parsing happens before that.
5705 // Even if autoloading is off and has no effect, triggering loading from external
5706 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5707 // from subsequent autoloads!
5708 return false;
5709 }
5710 private:
5711 std::unordered_set<const NamespaceDecl*>& fNSSet;
5712 };
5713}
5714
5715////////////////////////////////////////////////////////////////////////////////
5716/// Load map between class and library. If rootmapfile is specified a
5717/// specific rootmap file can be added (typically used by ACLiC).
5718/// In case of error -1 is returned, 0 otherwise.
5719/// The interpreter uses this information to automatically load the shared
5720/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5721
5722Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5723{
5724 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5725 return 0;
5726
5728
5729 // open the [system].rootmap files
5730 if (!fMapfile) {
5731 fMapfile = new TEnv();
5735 InitRootmapFile(".rootmap");
5736 }
5737
5738 // Prepare a list of all forward declarations for cling
5739 // For some experiments it is easily as big as 500k characters. To be on the
5740 // safe side, we go for 1M.
5741 TUniqueString uniqueString(1048576);
5742
5743 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5744 // A rootmap file must end with the string ".rootmap".
5745 TString ldpath = gSystem->GetDynamicPath();
5746 if (ldpath != fRootmapLoadPath) {
5747 fRootmapLoadPath = ldpath;
5748#ifdef WIN32
5749 TObjArray* paths = ldpath.Tokenize(";");
5750#else
5751 TObjArray* paths = ldpath.Tokenize(":");
5752#endif
5753 TString d;
5754 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5755 d = ((TObjString *)paths->At(i))->GetString();
5756 // check if directory already scanned
5757 Int_t skip = 0;
5758 for (Int_t j = 0; j < i; j++) {
5759 TString pd = ((TObjString *)paths->At(j))->GetString();
5760 if (pd == d) {
5761 skip++;
5762 break;
5763 }
5764 }
5765 if (!skip) {
5766 void* dirp = gSystem->OpenDirectory(d);
5767 if (dirp) {
5768 if (gDebug > 3) {
5769 Info("LoadLibraryMap", "%s", d.Data());
5770 }
5771 const char* f1;
5772 while ((f1 = gSystem->GetDirEntry(dirp))) {
5773 TString f = f1;
5774 if (f.EndsWith(".rootmap")) {
5775 TString p;
5776 p = d + "/" + f;
5778 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5779 if (gDebug > 4) {
5780 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5781 }
5782 Int_t ret = ReadRootmapFile(p, &uniqueString);
5783
5784 if (ret == 0)
5785 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5786 if (ret == -3) {
5787 // old format
5789 fRootmapFiles->Add(new TNamed(f, p));
5790 }
5791 }
5792 // else {
5793 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5794 // fRootmapFiles->FindObject(f)->ls();
5795 // }
5796 }
5797 }
5798 if (f.BeginsWith("rootmap")) {
5799 TString p;
5800 p = d + "/" + f;
5801 FileStat_t stat;
5802 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5803 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5804 }
5805 }
5806 }
5807 }
5808 gSystem->FreeDirectory(dirp);
5809 }
5810 }
5811 delete paths;
5812 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5813 return -1;
5814 }
5815 }
5816 if (rootmapfile && *rootmapfile) {
5817 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5818 if (res == 0) {
5819 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5820 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5821 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5822 }
5823 else if (res == -3) {
5824 // old format
5826 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5827 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5828 fMapfile->IgnoreDuplicates(ignore);
5829 }
5830 }
5831 TEnvRec* rec;
5832 TIter next(fMapfile->GetTable());
5833 while ((rec = (TEnvRec*) next())) {
5834 TString cls = rec->GetName();
5835 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5836 // get the first lib from the list of lib and dependent libs
5837 TString libs = rec->GetValue();
5838 if (libs == "") {
5839 continue;
5840 }
5841 TString delim(" ");
5842 TObjArray* tokens = libs.Tokenize(delim);
5843 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5844 // convert "@@" to "::", we used "@@" because TEnv
5845 // considers "::" a terminator
5846 cls.Remove(0, 8);
5847 cls.ReplaceAll("@@", "::");
5848 // convert "-" to " ", since class names may have
5849 // blanks and TEnv considers a blank a terminator
5850 cls.ReplaceAll("-", " ");
5851 if (gDebug > 6) {
5852 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5853 if (wlib) {
5854 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5855 }
5856 else {
5857 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5858 }
5859 delete[] wlib;
5860 }
5861 delete tokens;
5862 }
5863 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5864 cls.Remove(0, 8);
5865 // convert "-" to " ", since class names may have
5866 // blanks and TEnv considers a blank a terminator
5867 cls.ReplaceAll("-", " ");
5868 fInterpreter->declare(cls.Data());
5869 }
5870 }
5871
5872 // Process the forward declarations collected
5873 cling::Transaction* T = nullptr;
5874 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5875 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5876
5877 if (compRes!=cling::Interpreter::kSuccess){
5878 Warning("LoadLibraryMap",
5879 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5880 }
5881
5882 if (T) {
5883 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5884 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5885 if (declIt->m_DGR.isSingleDecl()) {
5886 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5887 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5888 evsAdder.TraverseDecl(D);
5889 }
5890 }
5891 }
5892 }
5893 }
5894
5895 // clear duplicates
5896
5897 return 0;
5898}
5899
5900////////////////////////////////////////////////////////////////////////////////
5901/// Scan again along the dynamic path for library maps. Entries for the loaded
5902/// shared libraries are unloaded first. This can be useful after reseting
5903/// the dynamic path through TSystem::SetDynamicPath()
5904/// In case of error -1 is returned, 0 otherwise.
5905
5907{
5910 return 0;
5911}
5912
5913////////////////////////////////////////////////////////////////////////////////
5914/// Reload the library map entries coming from all the loaded shared libraries,
5915/// after first unloading the current ones.
5916/// In case of error -1 is returned, 0 otherwise.
5917
5919{
5920 const TString sharedLibLStr = GetSharedLibs();
5921 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5922 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5923 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5924 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5925 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5926 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5927 if (ret < 0) {
5928 continue;
5929 }
5930 TString rootMapBaseStr = sharedLibBaseStr;
5931 if (sharedLibBaseStr.EndsWith(".dll")) {
5932 rootMapBaseStr.ReplaceAll(".dll", "");
5933 }
5934 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5935 rootMapBaseStr.ReplaceAll(".DLL", "");
5936 }
5937 else if (sharedLibBaseStr.EndsWith(".so")) {
5938 rootMapBaseStr.ReplaceAll(".so", "");
5939 }
5940 else if (sharedLibBaseStr.EndsWith(".sl")) {
5941 rootMapBaseStr.ReplaceAll(".sl", "");
5942 }
5943 else if (sharedLibBaseStr.EndsWith(".dl")) {
5944 rootMapBaseStr.ReplaceAll(".dl", "");
5945 }
5946 else if (sharedLibBaseStr.EndsWith(".a")) {
5947 rootMapBaseStr.ReplaceAll(".a", "");
5948 }
5949 else {
5950 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5951 delete sharedLibL;
5952 return -1;
5953 }
5954 rootMapBaseStr += ".rootmap";
5955 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5956 if (!rootMap) {
5957 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5958 delete[] rootMap;
5959 delete sharedLibL;
5960 return -1;
5961 }
5962 const Int_t status = LoadLibraryMap(rootMap);
5963 if (status < 0) {
5964 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5965 delete[] rootMap;
5966 delete sharedLibL;
5967 return -1;
5968 }
5969 delete[] rootMap;
5970 }
5971 delete sharedLibL;
5972 return 0;
5973}
5974
5975////////////////////////////////////////////////////////////////////////////////
5976/// Unload the library map entries coming from all the loaded shared libraries.
5977/// Returns 0 if succesful
5978
5980{
5981 const TString sharedLibLStr = GetSharedLibs();
5982 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5983 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5984 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5985 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5986 UnloadLibraryMap(sharedLibBaseStr);
5987 }
5988 delete sharedLibL;
5989 return 0;
5990}
5991
5992////////////////////////////////////////////////////////////////////////////////
5993/// Unload library map entries coming from the specified library.
5994/// Returns -1 in case no entries for the specified library were found,
5995/// 0 otherwise.
5996
5998{
5999 if (!fMapfile || !library || !*library) {
6000 return 0;
6001 }
6002 TString libname(library);
6003 Ssiz_t idx = libname.Last('.');
6004 if (idx != kNPOS) {
6005 libname.Remove(idx);
6006 }
6007 size_t len = libname.Length();
6008 TEnvRec *rec;
6009 TIter next(fMapfile->GetTable());
6011 Int_t ret = 0;
6012 while ((rec = (TEnvRec *) next())) {
6013 TString cls = rec->GetName();
6014 if (cls.Length() > 2) {
6015 // get the first lib from the list of lib and dependent libs
6016 TString libs = rec->GetValue();
6017 if (libs == "") {
6018 continue;
6019 }
6020 TString delim(" ");
6021 TObjArray* tokens = libs.Tokenize(delim);
6022 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6023 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6024 // convert "@@" to "::", we used "@@" because TEnv
6025 // considers "::" a terminator
6026 cls.Remove(0, 8);
6027 cls.ReplaceAll("@@", "::");
6028 // convert "-" to " ", since class names may have
6029 // blanks and TEnv considers a blank a terminator
6030 cls.ReplaceAll("-", " ");
6031 }
6032 if (!strncmp(lib, libname.Data(), len)) {
6033 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6034 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6035 ret = -1;
6036 }
6037 }
6038 delete tokens;
6039 }
6040 }
6041 if (ret >= 0) {
6042 TString library_rootmap(library);
6043 if (!library_rootmap.EndsWith(".rootmap"))
6044 library_rootmap.Append(".rootmap");
6045 TNamed* mfile = nullptr;
6046 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6047 fRootmapFiles->Remove(mfile);
6048 delete mfile;
6049 }
6051 }
6052 return ret;
6053}
6054
6055////////////////////////////////////////////////////////////////////////////////
6056/// Register the AutoLoading information for a class.
6057/// libs is a space separated list of libraries.
6058
6059Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6060{
6061 if (!cls || !*cls)
6062 return 0;
6063
6064 TString key = TString("Library.") + cls;
6065 // convert "::" to "@@", we used "@@" because TEnv
6066 // considers "::" a terminator
6067 key.ReplaceAll("::", "@@");
6068 // convert "-" to " ", since class names may have
6069 // blanks and TEnv considers a blank a terminator
6070 key.ReplaceAll(" ", "-");
6071
6073 if (!fMapfile) {
6074 fMapfile = new TEnv();
6076
6079
6080 InitRootmapFile(".rootmap");
6081 }
6082 //fMapfile->SetValue(key, libs);
6083 fMapfile->SetValue(cls, libs);
6084 return 1;
6085}
6086
6087////////////////////////////////////////////////////////////////////////////////
6088/// Demangle the name (from the typeinfo) and then request the class
6089/// via the usual name based interface (TClass::GetClass).
6090
6091TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6092{
6093 int err = 0;
6094 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6095 if (err) return nullptr;
6096 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6097 free(demangled_name);
6098 return theClass;
6099}
6100
6101////////////////////////////////////////////////////////////////////////////////
6102/// Load library containing the specified class. Returns 0 in case of error
6103/// and 1 in case if success.
6104
6105Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6106{
6107 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6108
6109 int err = 0;
6110 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6111 if (err) {
6112 return 0;
6113 }
6114
6115 std::string demangled_name(demangled_name_c);
6116 free(demangled_name_c);
6117
6118 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6119 // shortened name.
6121 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6122
6123 // No need to worry about typedef, they aren't any ... but there are
6124 // inlined namespaces ...
6125
6126 Int_t result = AutoLoad(demangled_name.c_str());
6127 if (result == 0) {
6128 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6129 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6130 }
6131
6132 return result;
6133}
6134
6135////////////////////////////////////////////////////////////////////////////////
6136// Get the list of 'published'/'known' library for the class and load them.
6138{
6139 Int_t status = 0;
6140
6141 // lookup class to find list of dependent libraries
6142 TString deplibs = gCling->GetClassSharedLibs(cls);
6143 if (!deplibs.IsNull()) {
6144 TString delim(" ");
6145 TObjArray* tokens = deplibs.Tokenize(delim);
6146 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6147 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6148 if (gROOT->LoadClass(cls, deplib) == 0) {
6149 if (gDebug > 0) {
6150 gCling->Info("TCling::AutoLoad",
6151 "loaded dependent library %s for %s", deplib, cls);
6152 }
6153 }
6154 else {
6155 gCling->Error("TCling::AutoLoad",
6156 "failure loading dependent library %s for %s",
6157 deplib, cls);
6158 }
6159 }
6160 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6161 if (lib && lib[0]) {
6162 if (gROOT->LoadClass(cls, lib) == 0) {
6163 if (gDebug > 0) {
6164 gCling->Info("TCling::AutoLoad",
6165 "loaded library %s for %s", lib, cls);
6166 }
6167 status = 1;
6168 }
6169 else {
6170 gCling->Error("TCling::AutoLoad",
6171 "failure loading library %s for %s", lib, cls);
6172 }
6173 }
6174 delete tokens;
6175 }
6176
6177 return status;
6178}
6179
6180////////////////////////////////////////////////////////////////////////////////
6181// Iterate through the data member of the class (either through the TProtoClass
6182// or through Cling) and trigger, recursively, the loading the necessary libraries.
6183// \note `cls` is expected to be already normalized!
6184// \returns 1 on success.
6185Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6186 bool nameIsNormalized)
6187{
6188 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6189 // has previously (within the same call to `AutoLoad()`) tried to load this class
6190 // and we are done, whether success or not, as it won't work better now than before,
6191 // because there is no additional information now compared to before.
6192 if (!visited.insert(std::string(cls)).second)
6193 return 1;
6194
6195 if (ShallowAutoLoadImpl(cls) == 0) {
6196 // If ShallowAutoLoadImpl() has an error, we have an error.
6197 return 0;
6198 }
6199
6200 // Now look through the TProtoClass to load the required library/dictionary
6201 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6202 for (auto element : proto->GetData()) {
6203 if (element->IsBasic())
6204 continue;
6205 const char *subtypename = element->GetTypeName();
6206 if (!TClassTable::GetDictNorm(subtypename)) {
6207 // Failure to load a dictionary is not (quite) a failure load
6208 // the top-level library. If we return false here, then
6209 // we would end up in a situation where the library and thus
6210 // the dictionary is loaded for "cls" but the TClass is
6211 // not created and/or marked as unavailable (in case where
6212 // AutoLoad is called from TClass::GetClass).
6213 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6214 }
6215 }
6216 return 1;
6217 }
6218
6219 // We found no TProtoClass for cls.
6220 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6221 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6222 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6223 {
6224 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6225 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6226 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6227 continue;
6228 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6229 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6230 // Failure to load a dictionary is not (quite) a failure load
6231 // the top-level library. See detailed comment in the TProtoClass
6232 // branch (above).
6233 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6234 }
6235 }
6236 gInterpreter->DataMemberInfo_Delete(memberinfo);
6237 }
6238 gInterpreter->ClassInfo_Delete(classinfo);
6239 return 1;
6240}
6241
6242////////////////////////////////////////////////////////////////////////////////
6243/// Load library containing the specified class. Returns 0 in case of error
6244/// and 1 in case if success.
6245
6246Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6247{
6248 // Prevent update to IsClassAutoloading between our check and our actions.
6250
6251 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6252 // rootcling (in *_rdict.pcm file generation) it is a no op.
6253 // FIXME: We should avoid calling autoload when we know we are not supposed
6254 // to and transform this check into an assert.
6256 // Never load any library from rootcling/genreflex.
6257 if (gDebug > 2) {
6258 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6259 }
6260 return 0;
6261 }
6262
6263 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6264
6266
6267 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6268 // The library is already loaded as the class's dictionary is known.
6269 // Return success.
6270 // Note: the name (cls) is expected to be normalized as it comes either
6271 // from a callbacks (that can/should calculate the normalized name from the
6272 // decl) or from TClass::GetClass (which does also calculate the normalized
6273 // name).
6274 return 1;
6275 }
6276
6277 if (gDebug > 2) {
6278 Info("TCling::AutoLoad",
6279 "Trying to autoload for %s", cls);
6280 }
6281
6282 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6283 if (gDebug > 2) {
6284 Info("TCling::AutoLoad",
6285 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6286 }
6287 return 0;
6288 }
6289 // Prevent the recursion when the library dictionary are loaded.
6290 SuspendAutoLoadingRAII autoLoadOff(this);
6291 // Try using externally provided callback first.
6292 if (fAutoLoadCallBack) {
6293 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6294 if (success)
6295 return success;
6296 }
6297
6298 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6299 // (when module are enabled) which might end up calling AutoParsing but
6300 // that should only be for the cases where the library has no generated pcm
6301 // and in that case a rootmap should be available.
6302 // This avoids a very costly operation (for generally no gain) but reduce the
6303 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6304 // file).
6305 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6306 std::unordered_set<std::string> visited;
6307 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6308}
6309
6310////////////////////////////////////////////////////////////////////////////////
6311/// Parse the payload or header.
6312
6313static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6314 Bool_t header,
6315 cling::Interpreter *interpreter)
6316{
6317 std::string code = gNonInterpreterClassDef ;
6318 if (!header) {
6319 // This is the complete header file content and not the
6320 // name of a header.
6321 code += what;
6322
6323 } else {
6324 code += ("#include \"");
6325 code += what;
6326 code += "\"\n";
6327 }
6328 code += ("#ifdef __ROOTCLING__\n"
6329 "#undef __ROOTCLING__\n"
6330 + gInterpreterClassDef +
6331 "#endif");
6332
6333 cling::Interpreter::CompilationResult cr;
6334 {
6335 // scope within which diagnostics are de-activated
6336 // For now we disable diagnostics because we saw them already at
6337 // dictionary generation time. That won't be an issue with the PCMs.
6338
6339 Sema &SemaR = interpreter->getSema();
6340 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6341 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6342
6343 #if defined(R__MUST_REVISIT)
6344 #if R__MUST_REVISIT(6,2)
6345 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6346 #endif
6347 #endif
6348
6349 cr = interpreter->parseForModule(code);
6350 }
6351 return cr;
6352}
6353
6354////////////////////////////////////////////////////////////////////////////////
6355/// Helper routine for TCling::AutoParse implementing the actual call to the
6356/// parser and looping over template parameters (if
6357/// any) and when they don't have a registered header to autoparse,
6358/// recurse over their template parameters.
6359///
6360/// Returns the number of header parsed.
6361
6362UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6363{
6364 // We assume the lock has already been taken.
6365 // R__LOCKGUARD(gInterpreterMutex);
6366
6367 Int_t nHheadersParsed = 0;
6368 unsigned long offset = 0;
6369 if (strncmp(cls, "const ", 6) == 0) {
6370 offset = 6;
6371 }
6372
6373 // Loop on the possible autoparse keys
6374 bool skipFirstEntry = false;
6375 std::vector<std::string> autoparseKeys;
6376 if (strchr(cls, '<')) {
6377 int nestedLoc = 0;
6378 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6379 // Check if we can skip the name of the template in the autoparses
6380 // Take all the scopes one by one. If all of them are in the AST, we do not
6381 // need to autoparse for that particular template.
6382 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6383 // autoparseKeys[0] is empty when the input is not a template instance.
6384 // The case strchr(cls, '<') != 0 but still not a template instance can
6385 // happens 'just' for string (GetSplit replaces the template by the short name
6386 // and then use that for thew splitting)
6387 TString templateName(autoparseKeys[0]);
6388 auto tokens = templateName.Tokenize("::");
6389 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6390 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6391 if (TClassEdit::IsStdClass(cls + offset))
6392 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6393 auto nTokens = tokens->GetEntriesFast();
6394 for (Int_t tk = 0; tk < nTokens; ++tk) {
6395 auto scopeObj = tokens->UncheckedAt(tk);
6396 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6397 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6398 // Check if we have multiple nodes in the AST with this name
6399 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6400 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6401 if (!previousScopeAsContext) break; // this is not a context
6402 }
6403 delete tokens;
6404 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6405 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6406 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6407 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6408 skipFirstEntry = templatedDecl->hasDefinition();
6409 }
6410 }
6411 }
6412
6413 }
6414 }
6415 if (topLevel) autoparseKeys.emplace_back(cls);
6416
6417 for (const auto & apKeyStr : autoparseKeys) {
6418 if (skipFirstEntry) {
6419 skipFirstEntry=false;
6420 continue;
6421 }
6422 if (apKeyStr.empty()) continue;
6423 const char *apKey = apKeyStr.c_str();
6424 std::size_t normNameHash(fStringHashFunction(apKey));
6425 // If the class was not looked up
6426 if (gDebug > 1) {
6427 Info("TCling::AutoParse",
6428 "Starting autoparse for %s\n", apKey);
6429 }
6430 if (fLookedUpClasses.insert(normNameHash).second) {
6431 auto const &iter = fClassesHeadersMap.find(normNameHash);
6432 if (iter != fClassesHeadersMap.end()) {
6433 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6434 fTransactionHeadersMap.insert({T,normNameHash});
6435 auto const &hNamesPtrs = iter->second;
6436 if (gDebug > 1) {
6437 Info("TCling::AutoParse",
6438 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6439 }
6440 for (auto & hName : hNamesPtrs) {
6441 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6442 if (0 != fPayloads.count(normNameHash)) {
6443 float initRSSval=0.f, initVSIZEval=0.f;
6444 (void) initRSSval; // Avoid unused var warning
6445 (void) initVSIZEval;
6446 if (gDebug > 0) {
6447 Info("AutoParse",
6448 "Parsing full payload for %s", apKey);
6449 ProcInfo_t info;
6450 gSystem->GetProcInfo(&info);
6451 initRSSval = 1e-3*info.fMemResident;
6452 initVSIZEval = 1e-3*info.fMemVirtual;
6453 }
6454 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6455 if (cRes != cling::Interpreter::kSuccess) {
6456 if (hName[0] == '\n')
6457 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6458 } else {
6459 fParsedPayloadsAddresses.insert(hName);
6460 nHheadersParsed++;
6461 if (gDebug > 0){
6462 ProcInfo_t info;
6463 gSystem->GetProcInfo(&info);
6464 float endRSSval = 1e-3*info.fMemResident;
6465 float endVSIZEval = 1e-3*info.fMemVirtual;
6466 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6467 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6468 }
6469 }
6470 } else if (!IsLoaded(hName)) {
6471 if (gDebug > 0) {
6472 Info("AutoParse",
6473 "Parsing single header %s", hName);
6474 }
6475 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6476 if (cRes != cling::Interpreter::kSuccess) {
6477 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6478 } else {
6479 nHheadersParsed++;
6480 }
6481 }
6482 }
6483 }
6484 else {
6485 // There is no header registered for this class, if this a
6486 // template, it will be instantiated if/when it is requested
6487 // and if we do no load/parse its components we might end up
6488 // not using an eventual specialization.
6489 if (strchr(apKey, '<')) {
6490 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6491 }
6492 }
6493 }
6494 }
6495
6496 return nHheadersParsed;
6497
6498}
6499
6500////////////////////////////////////////////////////////////////////////////////
6501/// Parse the headers relative to the class
6502/// Returns 1 in case of success, 0 in case of failure
6503
6504Int_t TCling::AutoParse(const char *cls)
6505{
6506 if (llvm::StringRef(cls).contains("(lambda)"))
6507 return 0;
6508
6511 return AutoLoad(cls);
6512 } else {
6513 return 0;
6514 }
6515 }
6516
6518
6519 if (gDebug > 1) {
6520 Info("TCling::AutoParse",
6521 "Trying to autoparse for %s", cls);
6522 }
6523
6524 // The catalogue of headers is in the dictionary
6526 && !gClassTable->GetDictNorm(cls)) {
6527 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6528 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6529 fInterpreter->getSema());
6530 AutoLoad(cls, true /*knowDictNotLoaded*/);
6531 }
6532
6533 // Prevent the recursion when the library dictionary are loaded.
6534 SuspendAutoLoadingRAII autoLoadOff(this);
6535
6536 // No recursive header parsing on demand; we require headers to be standalone.
6537 SuspendAutoParsing autoParseRAII(this);
6538
6539 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6540
6542
6543 return nHheadersParsed > 0 ? 1 : 0;
6544}
6545
6546// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6547// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6548// false if not.
6549bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6550{
6551 StringRef errMsg(errmessage);
6552 if (errMsg.contains("undefined symbol: ")) {
6553 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6554 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6555 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6556 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6557 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6558 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6559 return true;
6560 } else {
6561 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6562 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6563 return true;
6564 }
6565
6566 return false;
6567}
6568
6569////////////////////////////////////////////////////////////////////////////////
6570/// Autoload a library based on a missing symbol.
6571
6572void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6573 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6574
6575 // We have already loaded the library.
6576 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6577 return Addr;
6578
6579 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6581
6582 auto LibLoader = [](const std::string& LibName) -> bool {
6583 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6584 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6585 "Failed to load library %s", LibName.c_str());
6586 return false;
6587 }
6588 return true; //success.
6589 };
6590
6591 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6592 /*searchSystem=*/ true);
6593
6594 assert(!llvm::StringRef(libName).startswith("libNew") &&
6595 "We must not resolve symbols from libNew!");
6596
6597 if (libName.empty())
6598 return nullptr;
6599
6600 if (!LibLoader(libName))
6601 return nullptr;
6602
6603 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6604}
6605
6606////////////////////////////////////////////////////////////////////////////////
6607
6608Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6609{
6610 return fNSFromRootmaps.count(nsDecl) != 0;
6611}
6612
6613////////////////////////////////////////////////////////////////////////////////
6614/// Internal function. Actually do the update of the ClassInfo when seeing
6615// new TagDecl or NamespaceDecl.
6616void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6617{
6618
6620 if (cci) {
6621 // If we only had a forward declaration then update the
6622 // TClingClassInfo with the definition if we have it now.
6623 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6624 if (!oldDef || (def && def != oldDef)) {
6625 cl->ResetCaches();
6627 if (def) {
6628 // It's a tag decl, not a namespace decl.
6629 cci->Init(*cci->GetType());
6631 }
6632 }
6633 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6634 cl->ResetCaches();
6635 // yes, this is almost a waste of time, but we do need to lookup
6636 // the 'type' corresponding to the TClass anyway in order to
6637 // preserve the opaque typedefs (Double32_t)
6638 if (!alias && def != nullptr)
6639 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6640 else
6641 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6642 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6643 // We now need to update the state and bits.
6644 if (cl->fState != TClass::kHasTClassInit) {
6645 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6648 }
6649 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6650 } else {
6651 delete ((TClingClassInfo *)cl->fClassInfo);
6652 cl->fClassInfo = nullptr;
6653 }
6654 }
6655}
6656
6657////////////////////////////////////////////////////////////////////////////////
6658/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6659void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6660{
6661 const TagDecl *td = dyn_cast<TagDecl>(ND);
6662 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6663 const NamedDecl *canon = nullptr;
6664
6665 std::string name;
6666 TagDecl* tdDef = nullptr;
6667 if (td) {
6668 canon = tdDef = td->getDefinition();
6669 // Let's pass the decl to the TClass only if it has a definition.
6670 if (!tdDef) return;
6671
6672 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6673 // Ignore incomplete definition.
6674 // Ignore declaration within a function.
6675 return;
6676 }
6677
6678 auto declName = tdDef->getNameAsString();
6679 // Check if we have registered the unqualified name into the list
6680 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6681 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6682 // the unqualified name is sufficient (and the fully qualified name might be
6683 // 'wrong' if there is difference in spelling in the template paramters (for example)
6684 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6685 // 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() );
6686 return;
6687 }
6688
6689 clang::QualType type(tdDef->getTypeForDecl(), 0);
6691 } else if (ns) {
6692 canon = ns->getCanonicalDecl();
6693 name = ND->getQualifiedNameAsString();
6694 } else {
6695 name = ND->getQualifiedNameAsString();
6696 }
6697
6698 // Supposedly we are being called while something is being
6699 // loaded ... let's now tell the autoloader to do the work
6700 // yet another time.
6701 SuspendAutoLoadingRAII autoLoadOff(this);
6702 // FIXME: There can be more than one TClass for a single decl.
6703 // for example vector<double> and vector<Double32_t>
6704 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6705 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6706 RefreshClassInfo(cl, canon, false);
6707 }
6708 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6709 // and update them too:
6710 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6711 // RefreshClassInfo(cl, tdDef, true);
6712}
6713
6714////////////////////////////////////////////////////////////////////////////////
6715/// No op: see TClingCallbacks
6716
6717void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6718{
6719}
6720
6721//______________________________________________________________________________
6722//FIXME: Factor out that function in TClass, because TClass does it already twice
6723void TCling::UpdateClassInfoWork(const char* item)
6724{
6725 // This is a no-op as part of the API.
6726 // TCling uses UpdateClassInfoWithDecl() instead.
6727}
6728
6729////////////////////////////////////////////////////////////////////////////////
6730/// Update all canvases at end the terminal input command.
6731
6733{
6734 TIter next(gROOT->GetListOfCanvases());
6735 TVirtualPad* canvas;
6736 while ((canvas = (TVirtualPad*)next())) {
6737 canvas->Update();
6738 }
6739}
6740
6741////////////////////////////////////////////////////////////////////////////////
6742
6743void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6744 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6745
6746 // If the transaction does not contain anything we can return earlier.
6747 if (!HandleNewTransaction(T)) return;
6748
6749 bool isTUTransaction = false;
6750 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6751 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6752 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6753 // The is the first transaction, we have to expose to meta
6754 // what's already in the AST.
6755 isTUTransaction = true;
6756 }
6757 }
6758
6759 std::set<const void*> TransactionDeclSet;
6760 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6761 const clang::Decl* WrapperFD = T.getWrapperFD();
6762 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6763 I != E; ++I) {
6764 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6765 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6766 continue;
6767
6768 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6769 DE = I->m_DGR.end(); DI != DE; ++DI) {
6770 if (*DI == WrapperFD)
6771 continue;
6772 TransactionDeclSet.insert(*DI);
6773 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6774 }
6775 }
6776 }
6777
6778 // The above might trigger more decls to be deserialized.
6779 // Thus the iteration over the deserialized decls must be last.
6780 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6781 E = T.deserialized_decls_end(); I != E; ++I) {
6782 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6783 DE = I->m_DGR.end(); DI != DE; ++DI)
6784 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6785 //FIXME: HandleNewDecl should take DeclGroupRef
6786 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6787 modifiedTClasses);
6788 }
6789 }
6790
6791
6792 // When fully building the reflection info in TClass, a deserialization
6793 // could be triggered, which may result in request for building the
6794 // reflection info for the same TClass. This in turn will clear the caches
6795 // for the TClass in-flight and cause null ptr derefs.
6796 // FIXME: This is a quick fix, solving most of the issues. The actual
6797 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6798 // itself until the update is done.
6799 //
6800 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6801 std::vector<TClass*>::iterator it;
6802 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6803 ((TCling*)gCling)->GetModTClasses().begin(),
6804 ((TCling*)gCling)->GetModTClasses().end(),
6805 modifiedTClassesDiff.begin());
6806 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6807
6808 // Lock the TClass for updates
6809 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6810 modifiedTClassesDiff.end());
6811 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6812 E = modifiedTClassesDiff.end(); I != E; ++I) {
6813 // Make sure the TClass has not been deleted.
6814 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6815 continue;
6816 }
6817 // Could trigger deserialization of decls.
6818 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6819 // Unlock the TClass for updates
6820 ((TCling*)gCling)->GetModTClasses().erase(*I);
6821
6822 }
6823}
6824
6825///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6826///
6827void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6828{
6830
6831 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6832 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6833 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6834 (TListOfEnums *)gROOT->GetListOfEnums());
6835
6836 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6837 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6838 I != E; ++I) {
6839 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6840 continue;
6841 if (I->m_Call == cling::Transaction::kCCINone) {
6842 UpdateListsOnUnloaded(*(*iNested));
6843 ++iNested;
6844 continue;
6845 }
6846
6847 for (auto &D : I->m_DGR)
6848 InvalidateCachedDecl(Lists, D);
6849 }
6850}
6851
6852///\brief Invalidate cached TCling information for the given global declaration.
6853///
6854void TCling::InvalidateGlobal(const Decl *D) {
6855 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6856 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6857 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6858 (TListOfEnums *)gROOT->GetListOfEnums());
6859 InvalidateCachedDecl(Lists, D);
6860}
6861
6862///\brief Invalidate cached TCling information for the given declaration, and
6863/// removed it from the appropriate object list.
6864///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6865/// TListOfFunctionTemplates&, TListOfEnums&>
6866/// of pointers to the (global/class) object lists.
6867///\param[in] D - Decl to discard.
6868///
6872 TListOfEnums*> &Lists, const Decl *D) {
6873 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6874 return;
6875
6876 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6877 TListOfFunctions &LOF = *(std::get<1>(Lists));
6878 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6879 TListOfEnums &LOE = *(std::get<3>(Lists));
6880
6881 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6882 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6883 if (LODM.GetClass())
6884 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6885 else
6886 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6887 } else if (isa<FunctionDecl>(D)) {
6889 } else if (isa<FunctionTemplateDecl>(D)) {
6891 } else if (isa<EnumDecl>(D)) {
6892 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6893 if (!E)
6894 return;
6895
6896 // Try to invalidate enumerators (for unscoped enumerations).
6897 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6899 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6900
6902 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6903 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6904 return;
6905
6906 std::vector<TClass *> Classes;
6907 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6908 return;
6909 for (auto &C : Classes) {
6910 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6911 (TListOfFunctions *)C->GetListOfMethods(),
6912 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6913 (TListOfEnums *)C->GetListOfEnums());
6914 for (auto &I : cast<DeclContext>(D)->decls())
6915 InvalidateCachedDecl(Lists, I);
6916
6917 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6918 if (D->getKind() != Decl::Namespace
6919 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6920 C->ResetClassInfo();
6921 }
6922 }
6923}
6924
6925////////////////////////////////////////////////////////////////////////////////
6926// If an autoparse was done during a transaction and that it is rolled back,
6927// we need to make sure the next request for the same autoparse will be
6928// honored.
6929void TCling::TransactionRollback(const cling::Transaction &T) {
6930 auto const &triter = fTransactionHeadersMap.find(&T);
6931 if (triter != fTransactionHeadersMap.end()) {
6932 std::size_t normNameHash = triter->second;
6933
6934 fLookedUpClasses.erase(normNameHash);
6935
6936 auto const &iter = fClassesHeadersMap.find(normNameHash);
6937 if (iter != fClassesHeadersMap.end()) {
6938 auto const &hNamesPtrs = iter->second;
6939 for (auto &hName : hNamesPtrs) {
6940 if (gDebug > 0) {
6941 Info("TransactionRollback",
6942 "Restoring ability to autoaparse: %s", hName);
6943 }
6944 fParsedPayloadsAddresses.erase(hName);
6945 }
6946 }
6947 }
6948}
6949
6950////////////////////////////////////////////////////////////////////////////////
6951
6952void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6953// R__LOCKGUARD_CLING(gInterpreterMutex);
6954// UpdateListOfLoadedSharedLibraries();
6955}
6956
6957////////////////////////////////////////////////////////////////////////////////
6958
6959void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6960 fPrevLoadedDynLibInfo = nullptr;
6961 fSharedLibs = "";
6962}
6963
6964////////////////////////////////////////////////////////////////////////////////
6965/// Return the list of shared libraries loaded into the process.
6966
6968{
6971 return fSharedLibs;
6972}
6973
6974static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
6975{
6976 if (!cls || !*cls)
6977 return {};
6978
6979 using namespace clang;
6980 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6981 /*type*/ nullptr, /*instantiate*/ false)) {
6982 if (!D->isFromASTFile()) {
6983 if (gDebug > 5)
6984 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6985 return {};
6986 }
6987 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6988 llvm::DenseSet<Module *> &m_TopLevelModules;
6989
6990 public:
6991 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6992 void Collect(const Decl *D) { Visit(D); }
6993
6994 void VisitDecl(const Decl *D)
6995 {
6996 // FIXME: Such case is described ROOT-7765 where
6997 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6998 // They are specified as #includes in the LinkDef file. This leads to
6999 // generation of incomplete modulemap files and this logic fails to
7000 // compute the corresponding module of D.
7001 // FIXME: If we want to support such a case, we should not rely on
7002 // the contents of the modulemap but mangle D and look it up in the
7003 // .so files.
7004 if (!D->hasOwningModule())
7005 return;
7006 if (Module *M = D->getOwningModule()->getTopLevelModule())
7007 m_TopLevelModules.insert(M);
7008 }
7009
7010 void VisitTemplateArgument(const TemplateArgument &TA)
7011 {
7012 switch (TA.getKind()) {
7013 case TemplateArgument::Null:
7014 case TemplateArgument::Integral:
7015 case TemplateArgument::Pack:
7016 case TemplateArgument::NullPtr:
7017 case TemplateArgument::Expression:
7018 case TemplateArgument::Template:
7019 case TemplateArgument::TemplateExpansion: return;
7020 case TemplateArgument::Type:
7021 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7022 return Visit(TagTy->getDecl());
7023 return;
7024 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7025 }
7026 llvm_unreachable("Invalid TemplateArgument::Kind!");
7027 }
7028
7029 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7030 {
7031 if (CTSD->getOwningModule())
7032 VisitDecl(CTSD);
7033 else
7034 VisitDecl(CTSD->getSpecializedTemplate());
7035 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7036 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7037 VisitTemplateArgument(*Arg);
7038 }
7039 }
7040 };
7041
7042 llvm::DenseSet<Module *> TopLevelModules;
7043 ModuleCollector m(TopLevelModules);
7044 m.Collect(D);
7045 std::string result;
7046 for (auto M : TopLevelModules) {
7047 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7048 // link declaration.
7049 if (!M->LinkLibraries.size())
7050 continue;
7051 // We have preloaded the Core module thus libCore.so
7052 if (M->Name == "Core" && skipCore)
7053 continue;
7054 assert(M->LinkLibraries.size() == 1);
7055 if (!result.empty())
7056 result += ' ';
7057 result += M->LinkLibraries[0].Library;
7058 }
7059 return result;
7060 }
7061 return {};
7062}
7063
7064////////////////////////////////////////////////////////////////////////////////
7065/// Get the list of shared libraries containing the code for class cls.
7066/// The first library in the list is the one containing the class, the
7067/// others are the libraries the first one depends on. Returns 0
7068/// in case the library is not found.
7069/// \param cls the name of the class
7070/// \param skipCore if true (default), remove "Core" from the returned list
7071
7072const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7073{
7074 if (fCxxModulesEnabled) {
7075 // Lock the interpreter mutex before interacting with cling.
7076 // TODO: Can we move this further deep? In principle the lock should be in
7077 // GetClassSharedLibsForModule, but it might be needed also for
7078 // getLookupHelper?
7080 llvm::StringRef className = cls;
7081 // If we get a class name containing lambda, we cannot parse it and we
7082 // can exit early.
7083 // FIXME: This works around a bug when we are instantiating a template
7084 // make_unique and the substitution fails. Seen in most of the dataframe
7085 // tests.
7086 if (className.contains("(lambda)"))
7087 return nullptr;
7088 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7089 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7090 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7091 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7092 if (!libs.empty()) {
7093 fAutoLoadLibStorage.push_back(libs);
7094 return fAutoLoadLibStorage.back().c_str();
7095 }
7096 }
7097
7098 if (!cls || !*cls) {
7099 return nullptr;
7100 }
7101 // lookup class to find list of libraries
7102 if (fMapfile) {
7103 TEnvRec* libs_record = nullptr;
7104 libs_record = fMapfile->Lookup(cls);
7105 if (libs_record) {
7106 const char* libs = libs_record->GetValue();
7107 return (*libs) ? libs : nullptr;
7108 }
7109 else {
7110 // Try the old format...
7111 TString c = TString("Library.") + cls;
7112 // convert "::" to "@@", we used "@@" because TEnv
7113 // considers "::" a terminator
7114 c.ReplaceAll("::", "@@");
7115 // convert "-" to " ", since class names may have
7116 // blanks and TEnv considers a blank a terminator
7117 c.ReplaceAll(" ", "-");
7118 // Use TEnv::Lookup here as the rootmap file must start with Library.
7119 // and do not support using any stars (so we do not need to waste time
7120 // with the search made by TEnv::GetValue).
7121 TEnvRec* libs_record = nullptr;
7122 libs_record = fMapfile->Lookup(c);
7123 if (libs_record) {
7124 const char* libs = libs_record->GetValue();
7125 return (*libs) ? libs : nullptr;
7126 }
7127 }
7128 }
7129 return nullptr;
7130}
7131
7132/// This interface returns a list of dependent libraries in the form:
7133/// lib libA.so libB.so libC.so. The first library is the library we are
7134/// searching dependencies for.
7135/// Note: In order to speed up the search, we display the dependencies of the
7136/// libraries which are not yet loaded. For instance, if libB.so was already
7137/// loaded the list would contain: lib libA.so libC.so.
7138static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7139 cling::Interpreter *interp,
7140 bool skipLoadedLibs = true)
7141{
7142 TString LibFullPath(lib);
7143 if (!llvm::sys::path::is_absolute(lib)) {
7144 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7145 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7146 return "";
7147 }
7148 } else {
7149 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7150 lib = llvm::sys::path::filename(lib).str();
7151 }
7152
7153 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7154 if (!ObjF) {
7155 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7156 return "";
7157 }
7158
7159 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7160
7161 std::set<string> DedupSet;
7162 std::string Result = lib + ' ';
7163 for (const auto &S : BinObjFile->symbols()) {
7164 uint32_t Flags = llvm::cantFail(S.getFlags());
7165 // Skip defined symbols: we have them.
7166 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7167 continue;
7168 // Skip undefined weak symbols: if we don't have them we won't need them.
7169 // `__gmon_start__` being a typical example.
7170 if (Flags & llvm::object::SymbolRef::SF_Weak)
7171 continue;
7172 llvm::Expected<StringRef> SymNameErr = S.getName();
7173 if (!SymNameErr) {
7174 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7175 continue;
7176 }
7177 llvm::StringRef SymName = SymNameErr.get();
7178 if (SymName.empty())
7179 continue;
7180
7181 if (BinObjFile->isELF()) {
7182 // Skip the symbols which are part of the C/C++ runtime and have a
7183 // fixed library version. See binutils ld VERSION. Those reside in
7184 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7185 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7186 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7187 continue;
7188
7189 // Those are 'weak undefined' symbols produced by gcc. We can
7190 // ignore them.
7191 // FIXME: It is unclear whether we can ignore all weak undefined
7192 // symbols:
7193 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7194 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7195 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7196 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7197 if (SymName == RegisterClasses ||
7198 SymName == RegisterCloneTable ||
7199 SymName == DeregisterCloneTable)
7200 continue;
7201 }
7202
7203 // If we can find the address of the symbol, we have loaded it. Skip.
7204 if (skipLoadedLibs) {
7205 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7206 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7207 continue;
7208 }
7209
7211 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7212 // The expected output is just filename without the full path, which
7213 // is not very accurate, because our Dyld implementation might find
7214 // a match in location a/b/c.so and if we return just c.so ROOT might
7215 // resolve it to y/z/c.so and there we might not be ABI compatible.
7216 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7217 if (!found.empty()) {
7218 std::string cand = llvm::sys::path::filename(found).str();
7219 if (!DedupSet.insert(cand).second)
7220 continue;
7221
7222 Result += cand + ' ';
7223 }
7224 }
7225
7226 return Result;
7227}
7228
7229static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7230{
7231 // Check if we have parsed a rootmap file.
7232 llvm::SmallString<256> rootmapName;
7233 if (!lib.startswith("lib"))
7234 rootmapName.append("lib");
7235
7236 rootmapName.append(llvm::sys::path::filename(lib));
7237 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7238
7239 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7240 return true;
7241
7242 // Perform a last resort by dropping the lib prefix.
7243 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7244 if (rootmapNameNoLib.consume_front("lib"))
7245 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7246
7247 return false;
7248}
7249
7250static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7251{
7252 if (gCling->HasPCMForLibrary(lib.data()))
7253 return true;
7254
7255 return hasParsedRootmapForLibrary(lib);
7256}
7257
7258////////////////////////////////////////////////////////////////////////////////
7259/// Get the list a libraries on which the specified lib depends. The
7260/// returned string contains as first element the lib itself.
7261/// Returns 0 in case the lib does not exist or does not have
7262/// any dependencies. If useDyld is true, we iterate through all available
7263/// libraries and try to construct the dependency chain by resolving each
7264/// symbol.
7265
7266const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7267{
7268 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7269 return nullptr;
7270
7271 if (!hasParsedRootmapForLibrary(lib)) {
7272 llvm::SmallString<512> rootmapName(lib);
7273 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7274 if (llvm::sys::fs::exists(rootmapName)) {
7275 if (gDebug > 0)
7276 Info("Load", "loading %s", rootmapName.c_str());
7277 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7278 }
7279 }
7280
7281 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7282 if (gDebug > 0)
7283 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7284 }
7285
7286 if (useDyld) {
7287 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7288 if (!libs.empty()) {
7289 fAutoLoadLibStorage.push_back(libs);
7290 return fAutoLoadLibStorage.back().c_str();
7291 }
7292 }
7293
7294 if (!fMapfile || !lib || !lib[0]) {
7295 return nullptr;
7296 }
7297 TString libname(lib);
7298 Ssiz_t idx = libname.Last('.');
7299 if (idx != kNPOS) {
7300 libname.Remove(idx);
7301 }
7302 TEnvRec* rec;
7303 TIter next(fMapfile->GetTable());
7304 size_t len = libname.Length();
7305 while ((rec = (TEnvRec*) next())) {
7306 const char* libs = rec->GetValue();
7307 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7308 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7309 return libs;
7310 }
7311 }
7312 return nullptr;
7313}
7314
7315////////////////////////////////////////////////////////////////////////////////
7316/// If error messages are disabled, the interpreter should suppress its
7317/// failures and warning messages from stdout.
7318
7320{
7321#if defined(R__MUST_REVISIT)
7322#if R__MUST_REVISIT(6,2)
7323 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7324#endif
7325#endif
7326 return kTRUE;
7327}
7328
7329////////////////////////////////////////////////////////////////////////////////
7330/// If error messages are disabled, the interpreter should suppress its
7331/// failures and warning messages from stdout. Return the previous state.
7332
7334{
7335#if defined(R__MUST_REVISIT)
7336#if R__MUST_REVISIT(6,2)
7337 Warning("SetErrorMessages", "Interface not available yet.");
7338#endif
7339#endif
7341}
7342
7343////////////////////////////////////////////////////////////////////////////////
7344/// Refresh the list of include paths known to the interpreter and return it
7345/// with -I prepended.
7346
7348{
7350
7351 fIncludePath = "";
7352
7353 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7354 //false - no system header, true - with flags.
7355 fInterpreter->GetIncludePaths(includePaths, false, true);
7356 if (const size_t nPaths = includePaths.size()) {
7357 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7358
7359 for (size_t i = 0; i < nPaths; i += 2) {
7360 if (i)
7361 fIncludePath.Append(' ');
7362 fIncludePath.Append(includePaths[i].c_str());
7363
7364 if (includePaths[i] != "-I")
7365 fIncludePath.Append(' ');
7366 fIncludePath.Append('"');
7367 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7368 fIncludePath.Append('"');
7369 }
7370 }
7371
7372 return fIncludePath;
7373}
7374
7375////////////////////////////////////////////////////////////////////////////////
7376/// Return the directory containing CINT's stl cintdlls.
7377
7378const char* TCling::GetSTLIncludePath() const
7379{
7380 return "";
7381}
7382
7383//______________________________________________________________________________
7384// M I S C
7385//______________________________________________________________________________
7386
7387int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7388{
7389 // Interface to cling function
7390 return 0;
7391}
7392
7393////////////////////////////////////////////////////////////////////////////////
7394/// Interface to cling function
7395
7396int TCling::DisplayIncludePath(FILE *fout) const
7397{
7398 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7399
7400 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7401 //false - no system header, true - with flags.
7402 fInterpreter->GetIncludePaths(includePaths, false, true);
7403 if (const size_t nPaths = includePaths.size()) {
7404 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7405
7406 std::string allIncludes("include path:");
7407 for (size_t i = 0; i < nPaths; i += 2) {
7408 allIncludes += ' ';
7409 allIncludes += includePaths[i];
7410
7411 if (includePaths[i] != "-I")
7412 allIncludes += ' ';
7413 allIncludes += includePaths[i + 1];
7414 }
7415
7416 fprintf(fout, "%s\n", allIncludes.c_str());
7417 }
7418
7419 return 0;
7420}
7421
7422////////////////////////////////////////////////////////////////////////////////
7423/// Interface to cling function
7424
7425void* TCling::FindSym(const char* entry) const
7426{
7427 return fInterpreter->getAddressOfGlobal(entry);
7428}
7429
7430////////////////////////////////////////////////////////////////////////////////
7431/// Let the interpreter issue a generic error, and set its error state.
7432
7433void TCling::GenericError(const char* error) const
7434{
7435#if defined(R__MUST_REVISIT)
7436#if R__MUST_REVISIT(6,2)
7437 Warning("GenericError","Interface not available yet.");
7438#endif
7439#endif
7440}
7441
7442////////////////////////////////////////////////////////////////////////////////
7443/// This routines used to return the address of the internal wrapper
7444/// function (of the interpreter) that was used to call *all* the
7445/// interpreted functions that were bytecode compiled (no longer
7446/// interpreted line by line). In Cling, there is no such
7447/// wrapper function.
7448/// In practice this routines was use to decipher whether the
7449/// pointer returns by InterfaceMethod could be used to uniquely
7450/// represent the function. In Cling if the function is in a
7451/// useable state (its compiled version is available), this is
7452/// always the case.
7453/// See TClass::GetMethod.
7454
7456{
7457 return 0;
7458}
7459
7460////////////////////////////////////////////////////////////////////////////////
7461/// Interface to cling function
7462
7464{
7465#if defined(R__MUST_REVISIT)
7466#if R__MUST_REVISIT(6,2)
7467 Warning("GetSecurityError", "Interface not available yet.");
7468#endif
7469#endif
7470 return 0;
7471}
7472
7473////////////////////////////////////////////////////////////////////////////////
7474/// Load a source file or library called path into the interpreter.
7475
7476int TCling::LoadFile(const char* path) const
7477{
7478 // Modifying the interpreter state needs locking.
7480 cling::Interpreter::CompilationResult compRes;
7481 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7482 return compRes == cling::Interpreter::kFailure;
7483}
7484
7485////////////////////////////////////////////////////////////////////////////////
7486/// Load the declarations from text into the interpreter.
7487/// Note that this cannot be (top level) statements; text must contain
7488/// top level declarations.
7489/// Returns true on success, false on failure.
7490
7491Bool_t TCling::LoadText(const char* text) const
7492{
7493 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7494}
7495
7496////////////////////////////////////////////////////////////////////////////////
7497/// Interface to cling function
7498
7499const char* TCling::MapCppName(const char* name) const
7500{
7501 TTHREAD_TLS_DECL(std::string,buffer);
7503 return buffer.c_str(); // NOLINT
7504}
7505
7506////////////////////////////////////////////////////////////////////////////////
7507/// [Place holder for Mutex Lock]
7508/// Provide the interpreter with a way to
7509/// acquire a lock used to protect critical section
7510/// of its code (non-thread safe parts).
7511
7512void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7513{
7514 // nothing to do for now.
7515}
7516
7517////////////////////////////////////////////////////////////////////////////////
7518/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7519/// release a lock used to protect critical section
7520/// of its code (non-thread safe parts).
7521
7522void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7523{
7524 // nothing to do for now.
7525}
7526
7527////////////////////////////////////////////////////////////////////////////////
7528/// Returns if class AutoLoading is currently enabled.
7529
7531{
7532 if (IsFromRootCling())
7533 return false;
7534 if (!fClingCallbacks)
7535 return false;
7537}
7538
7539////////////////////////////////////////////////////////////////////////////////
7540/// Enable/Disable the AutoLoading of libraries.
7541/// Returns the old value, i.e whether it was enabled or not.
7542
7543int TCling::SetClassAutoLoading(int autoload) const
7544{
7545 // If no state change is required, exit early.
7546 // FIXME: In future we probably want to complain if we made a request which
7547 // was with the same state as before in order to catch programming errors.
7548 if ((bool) autoload == IsClassAutoLoadingEnabled())
7549 return autoload;
7550
7551 assert(fClingCallbacks && "We must have callbacks!");
7552 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7554 return oldVal;
7555}
7556
7557////////////////////////////////////////////////////////////////////////////////
7558/// Enable/Disable the Autoparsing of headers.
7559/// Returns the old value, i.e whether it was enabled or not.
7560
7562{
7563 bool oldVal = fHeaderParsingOnDemand;
7564 fHeaderParsingOnDemand = autoparse;
7565 return oldVal;
7566}
7567
7568////////////////////////////////////////////////////////////////////////////////
7569/// Suspend the Autoparsing of headers.
7570/// Returns the old value, i.e whether it was suspended or not.
7571
7576 return old;
7577}
7578
7579////////////////////////////////////////////////////////////////////////////////
7580/// Set a callback to receive error messages.
7581
7583{
7584#if defined(R__MUST_REVISIT)
7585#if R__MUST_REVISIT(6,2)
7586 Warning("SetErrmsgcallback", "Interface not available yet.");
7587#endif
7588#endif
7589}
7590
7592{
7593 if (enable) {
7594 auto consumer = new TClingDelegateDiagnosticPrinter(
7595 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7596 fInterpreter->getCI()->getLangOpts(),
7597 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7598 if (Level == clang::DiagnosticsEngine::Warning) {
7599 ::Warning("cling", "%s", Info.c_str());
7600 } else if (Level == clang::DiagnosticsEngine::Error
7601 || Level == clang::DiagnosticsEngine::Fatal) {
7602 ::Error("cling", "%s", Info.c_str());
7603 } else {
7604 ::Info("cling", "%s", Info.c_str());
7605 }
7606 });
7607 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7608 } else {
7609 fInterpreter->replaceDiagnosticConsumer(nullptr);
7610 }
7611}
7612
7613
7614////////////////////////////////////////////////////////////////////////////////
7615/// Create / close a scope for temporaries. No-op for cling; use
7616/// cling::Value instead.
7617
7618void TCling::SetTempLevel(int val) const
7619{
7620}
7621
7622////////////////////////////////////////////////////////////////////////////////
7623
7624int TCling::UnloadFile(const char* path) const
7625{
7626 // Modifying the interpreter state needs locking.
7628 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7629 std::string canonical = DLM->lookupLibrary(path);
7630 if (canonical.empty()) {
7631 canonical = path;
7632 }
7633 // Unload a shared library or a source file.
7634 cling::Interpreter::CompilationResult compRes;
7635 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7636 return compRes == cling::Interpreter::kFailure;
7637}
7638
7639std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7640 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644/// The call to Cling's tab complition.
7645
7646void TCling::CodeComplete(const std::string& line, size_t& cursor,
7647 std::vector<std::string>& completions)
7648{
7649 fInterpreter->codeComplete(line, cursor, completions);
7650}
7651
7652////////////////////////////////////////////////////////////////////////////////
7653/// Get the interpreter value corresponding to the statement.
7655{
7656 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7657 auto compRes = fInterpreter->evaluate(code, *V);
7658 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7659}
7660
7661////////////////////////////////////////////////////////////////////////////////
7662
7664{
7665 using namespace cling;
7666 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7668}
7669
7670////////////////////////////////////////////////////////////////////////////////
7671/// Register value as a temporary, extending its lifetime to that of the
7672/// interpreter. This is needed for TCling's compatibility interfaces
7673/// returning long - the address of the temporary objects.
7674/// As such, "simple" types don't need to be stored; they are returned by
7675/// value; only pointers / references / objects need to be stored.
7676
7677void TCling::RegisterTemporary(const cling::Value& value)
7678{
7679 if (value.isValid() && value.needsManagedAllocation()) {
7681 fTemporaries->push_back(value);
7682 }
7683}
7684
7685////////////////////////////////////////////////////////////////////////////////
7686/// If the interpreter encounters Name, check whether that is an object ROOT
7687/// could retrieve. To not re-read objects from disk, cache the name/object
7688/// pair for a given LookupCtx.
7689
7690TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7691{
7692 // The call to FindSpecialObject might induces any kind of use
7693 // of the interpreter ... (library loading, function calling, etc.)
7694 // ... and we _know_ we are in the middle of parsing, so let's make
7695 // sure to save the state and then restore it.
7696
7697 if (gDirectory) {
7698 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7699 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7700 auto iSpecObj = iSpecObjMap->second.find(Name);
7701 if (iSpecObj != iSpecObjMap->second.end()) {
7702 LookupCtx = gDirectory;
7703 return iSpecObj->second;
7704 }
7705 }
7706 }
7707
7708 // Save state of the PP
7709 Sema &SemaR = fInterpreter->getSema();
7710 ASTContext& C = SemaR.getASTContext();
7711 Preprocessor &PP = SemaR.getPreprocessor();
7712 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7713 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7714 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7715 // After we have saved the token reset the current one to something which
7716 // is safe (semi colon usually means empty decl)
7717 Token& Tok = const_cast<Token&>(P.getCurToken());
7718 Tok.setKind(tok::semi);
7719
7720 // We can't PushDeclContext, because we go up and the routine that pops
7721 // the DeclContext assumes that we drill down always.
7722 // We have to be on the global context. At that point we are in a
7723 // wrapper function so the parent context must be the global.
7724 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7725 SemaR.TUScope);
7726
7727 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7728 if (specObj) {
7729 if (!LookupCtx) {
7730 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7731 } else {
7732 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7733 }
7734 }
7735 return specObj;
7736}
7737
7738////////////////////////////////////////////////////////////////////////////////
7739/// Inject function as a friend into klass.
7740/// With function being f in void f() {new N::PrivKlass(); } this enables
7741/// I/O of non-public classes.
7742
7743void TCling::AddFriendToClass(clang::FunctionDecl* function,
7744 clang::CXXRecordDecl* klass) const
7745{
7746 using namespace clang;
7747 ASTContext& Ctx = klass->getASTContext();
7748 FriendDecl::FriendUnion friendUnion(function);
7749 // one dummy object for the source location
7750 SourceLocation sl;
7751 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7752 klass->pushFriendDecl(friendDecl);
7753}
7754
7755//______________________________________________________________________________
7756//
7757// DeclId getter.
7758//
7759
7760////////////////////////////////////////////////////////////////////////////////
7761/// Return a unique identifier of the declaration represented by the
7762/// CallFunc
7763
7765{
7766 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7767 return nullptr;
7768}
7769
7770////////////////////////////////////////////////////////////////////////////////
7771/// Return a (almost) unique identifier of the declaration represented by the
7772/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7773/// when the underlying class is a template instance involving one of the
7774/// opaque typedef.
7775
7777{
7778 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7779 return nullptr;
7780}
7781
7782////////////////////////////////////////////////////////////////////////////////
7783/// Return a unique identifier of the declaration represented by the
7784/// MethodInfo
7785
7787{
7788 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7789 return nullptr;
7790}
7791
7792////////////////////////////////////////////////////////////////////////////////
7793/// Return a unique identifier of the declaration represented by the
7794/// MethodInfo
7795
7797{
7798 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7799 return nullptr;
7800}
7801
7802////////////////////////////////////////////////////////////////////////////////
7803/// Return a unique identifier of the declaration represented by the
7804/// TypedefInfo
7805
7807{
7808 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7809 return nullptr;
7810}
7811
7812//______________________________________________________________________________
7813//
7814// CallFunc interface
7815//
7816
7817////////////////////////////////////////////////////////////////////////////////
7818
7819void TCling::CallFunc_Delete(CallFunc_t* func) const
7820{
7821 delete (TClingCallFunc*) func;
7822}
7823
7824////////////////////////////////////////////////////////////////////////////////
7825
7826void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7827{
7828 TClingCallFunc* f = (TClingCallFunc*) func;
7829 f->Exec(address);
7830}
7831
7832////////////////////////////////////////////////////////////////////////////////
7833
7834void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7835{
7836 TClingCallFunc* f = (TClingCallFunc*) func;
7837 f->Exec(address, &val);
7838}
7839
7840////////////////////////////////////////////////////////////////////////////////
7841
7842void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7843{
7844 TClingCallFunc* f = (TClingCallFunc*) func;
7845 f->ExecWithReturn(address, ret);
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849
7850void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7851 const void* args[] /*=0*/,
7852 int nargs /*=0*/,
7853 void* ret/*=0*/) const
7854{
7855 TClingCallFunc* f = (TClingCallFunc*) func;
7856 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860
7861Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7862{
7863 TClingCallFunc* f = (TClingCallFunc*) func;
7864 return f->ExecInt(address);
7865}
7866
7867////////////////////////////////////////////////////////////////////////////////
7868
7869Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7870{
7871 TClingCallFunc* f = (TClingCallFunc*) func;
7872 return f->ExecInt64(address);
7873}
7874
7875////////////////////////////////////////////////////////////////////////////////
7876
7877Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7878{
7879 TClingCallFunc* f = (TClingCallFunc*) func;
7880 return f->ExecDouble(address);
7881}
7882
7883////////////////////////////////////////////////////////////////////////////////
7884
7885CallFunc_t* TCling::CallFunc_Factory() const
7886{
7888 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7889}
7890
7891////////////////////////////////////////////////////////////////////////////////
7892
7893CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7894{
7895 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7896}
7897
7898////////////////////////////////////////////////////////////////////////////////
7899
7900MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7901{
7902 TClingCallFunc* f = (TClingCallFunc*) func;
7903 return (MethodInfo_t*) f->FactoryMethod();
7904}
7905
7906////////////////////////////////////////////////////////////////////////////////
7907
7908void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7909{
7910 TClingCallFunc* f = (TClingCallFunc*) func;
7911 f->IgnoreExtraArgs(ignore);
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915
7916void TCling::CallFunc_Init(CallFunc_t* func) const
7917{
7919 TClingCallFunc* f = (TClingCallFunc*) func;
7920 f->Init();
7921}
7922
7923////////////////////////////////////////////////////////////////////////////////
7924
7925bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7926{
7927 TClingCallFunc* f = (TClingCallFunc*) func;
7928 return f->IsValid();
7929}
7930
7931////////////////////////////////////////////////////////////////////////////////
7932
7934TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7935{
7936 TClingCallFunc* f = (TClingCallFunc*) func;
7937 return f->IFacePtr();
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941
7942void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7943{
7944 TClingCallFunc* f = (TClingCallFunc*) func;
7945 f->ResetArg();
7946}
7947
7948////////////////////////////////////////////////////////////////////////////////
7949
7950void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7951{
7952 TClingCallFunc* f = (TClingCallFunc*) func;
7953 f->SetArg(param);
7954}
7955
7956////////////////////////////////////////////////////////////////////////////////
7957
7958void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7959{
7960 TClingCallFunc* f = (TClingCallFunc*) func;
7961 f->SetArg(param);
7962}
7963
7964////////////////////////////////////////////////////////////////////////////////
7965
7966void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7967{
7968 TClingCallFunc* f = (TClingCallFunc*) func;
7969 f->SetArg(param);
7970}
7971
7972////////////////////////////////////////////////////////////////////////////////
7973
7974void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7975{
7976 TClingCallFunc* f = (TClingCallFunc*) func;
7977 f->SetArg(param);
7978}
7979
7980////////////////////////////////////////////////////////////////////////////////
7981
7982void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7983{
7984 TClingCallFunc* f = (TClingCallFunc*) func;
7985 f->SetArg(param);
7986}
7987
7988////////////////////////////////////////////////////////////////////////////////
7989
7990void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7991{
7992 TClingCallFunc* f = (TClingCallFunc*) func;
7993 f->SetArg(param);
7994}
7995
7996////////////////////////////////////////////////////////////////////////////////
7997
7998void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
7999{
8000 TClingCallFunc* f = (TClingCallFunc*) func;
8001 f->SetArgArray(paramArr, nparam);
8002}
8003
8004////////////////////////////////////////////////////////////////////////////////
8005
8006void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8007{
8008 TClingCallFunc* f = (TClingCallFunc*) func;
8009 f->SetArgs(param);
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013
8014void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8015{
8016 TClingCallFunc* f = (TClingCallFunc*) func;
8017 TClingClassInfo* ci = (TClingClassInfo*) info;
8018 f->SetFunc(ci, method, params, offset);
8019}
8020
8021////////////////////////////////////////////////////////////////////////////////
8022
8023void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8024{
8025 TClingCallFunc* f = (TClingCallFunc*) func;
8026 TClingClassInfo* ci = (TClingClassInfo*) info;
8027 f->SetFunc(ci, method, params, objectIsConst, offset);
8028}
8029////////////////////////////////////////////////////////////////////////////////
8030
8031void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8032{
8033 TClingCallFunc* f = (TClingCallFunc*) func;
8034 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8035 f->SetFunc(minfo);
8036}
8037
8038////////////////////////////////////////////////////////////////////////////////
8039/// Interface to cling function
8040
8041void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8042{
8043 TClingCallFunc* f = (TClingCallFunc*) func;
8044 TClingClassInfo* ci = (TClingClassInfo*) info;
8045 f->SetFuncProto(ci, method, proto, offset, mode);
8046}
8047
8048////////////////////////////////////////////////////////////////////////////////
8049/// Interface to cling function
8050
8051void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8052{
8053 TClingCallFunc* f = (TClingCallFunc*) func;
8054 TClingClassInfo* ci = (TClingClassInfo*) info;
8055 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8056}
8057
8058////////////////////////////////////////////////////////////////////////////////
8059/// Interface to cling function
8060
8061void 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
8062{
8063 TClingCallFunc* f = (TClingCallFunc*) func;
8064 TClingClassInfo* ci = (TClingClassInfo*) info;
8065 llvm::SmallVector<clang::QualType, 4> funcProto;
8066 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8067 iter != end; ++iter) {
8068 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8069 }
8070 f->SetFuncProto(ci, method, funcProto, offset, mode);
8071}
8072
8073////////////////////////////////////////////////////////////////////////////////
8074/// Interface to cling function
8075
8076void 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
8077{
8078 TClingCallFunc* f = (TClingCallFunc*) func;
8079 TClingClassInfo* ci = (TClingClassInfo*) info;
8080 llvm::SmallVector<clang::QualType, 4> funcProto;
8081 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8082 iter != end; ++iter) {
8083 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8084 }
8085 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8086}
8087
8088std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8089{
8090 TClingCallFunc *f = (TClingCallFunc *)func;
8091 std::string wrapper_name;
8092 std::string wrapper;
8093 f->get_wrapper_code(wrapper_name, wrapper);
8094 return wrapper;
8095}
8096
8097//______________________________________________________________________________
8098//
8099// ClassInfo interface
8100//
8101
8102////////////////////////////////////////////////////////////////////////////////
8103/// Return true if the entity pointed to by 'declid' is declared in
8104/// the context described by 'info'. If info is null, look into the
8105/// global scope (translation unit scope).
8106
8107Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8108{
8109 if (!declid)
8110 return kFALSE;
8111
8112 const clang::DeclContext *ctxt = nullptr;
8113 if (info) {
8114 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8115 } else {
8116 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8117 }
8118 if (!ctxt)
8119 return kFALSE;
8120
8121 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8122 if (!decl)
8123 return kFALSE;
8124
8125 const clang::DeclContext *declDC = decl->getDeclContext();
8126 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8127 while (true) {
8128 if (declDC->isTransparentContext()) {
8129 declDC = declDC->getParent();
8130 continue;
8131 }
8132 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8133 if (declRD->isAnonymousStructOrUnion()) {
8134 declDC = declRD->getParent();
8135 continue;
8136 }
8137 }
8138 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8139 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8140 declDC = declNS->getParent();
8141 continue;
8142 }
8143 }
8144 break;
8145 }
8146
8147 return declDC->Equals(ctxt);
8148}
8149
8150////////////////////////////////////////////////////////////////////////////////
8151
8153{
8154 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8155 return TClinginfo->ClassProperty();
8156}
8157
8158////////////////////////////////////////////////////////////////////////////////
8159
8160void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8161{
8162 delete (TClingClassInfo*) cinfo;
8163}
8164
8165////////////////////////////////////////////////////////////////////////////////
8166
8167void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8168{
8169 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8170 TClinginfo->Delete(arena,*fNormalizedCtxt);
8171}
8172
8173////////////////////////////////////////////////////////////////////////////////
8174
8175void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8176{
8177 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8178 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8179}
8180
8181////////////////////////////////////////////////////////////////////////////////
8182
8183void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8184{
8185 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8186 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8187}
8188
8189////////////////////////////////////////////////////////////////////////////////
8190
8191ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8192{
8194 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8195}
8196
8197////////////////////////////////////////////////////////////////////////////////
8198
8199ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8200{
8201 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8202}
8203
8204////////////////////////////////////////////////////////////////////////////////
8205
8206ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8207{
8209 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8210}
8211
8212ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8213{
8215 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8216}
8217
8218
8219////////////////////////////////////////////////////////////////////////////////
8220
8221int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8222{
8223 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8224 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8225}
8226
8227////////////////////////////////////////////////////////////////////////////////
8228
8229bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8230{
8231 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8233}
8234
8235////////////////////////////////////////////////////////////////////////////////
8236
8237bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8238{
8239 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8240 return TClinginfo->HasMethod(name);
8241}
8242
8243////////////////////////////////////////////////////////////////////////////////
8244
8245void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8246{
8248 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8249 TClinginfo->Init(name);
8250}
8251
8252////////////////////////////////////////////////////////////////////////////////
8253
8254void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8255{
8257 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8258 TClinginfo->Init(tagnum);
8259}
8260
8261////////////////////////////////////////////////////////////////////////////////
8262
8263bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8264{
8265 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8266 return TClinginfo->IsBase(name);
8267}
8268
8269////////////////////////////////////////////////////////////////////////////////
8270
8271bool TCling::ClassInfo_IsEnum(const char* name) const
8272{
8274}
8275
8276////////////////////////////////////////////////////////////////////////////////
8277
8279{
8280 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8281 return TClinginfo->IsScopedEnum();
8282}
8283
8284
8285////////////////////////////////////////////////////////////////////////////////
8286
8288{
8289 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8290 return TClinginfo->GetUnderlyingType();
8291}
8292
8293
8294////////////////////////////////////////////////////////////////////////////////
8295
8296bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8297{
8298 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8299 return TClinginfo->IsLoaded();
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303
8304bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8305{
8306 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8307 return TClinginfo->IsValid();
8308}
8309
8310////////////////////////////////////////////////////////////////////////////////
8311
8312bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8313{
8314 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8315 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8316}
8317
8318////////////////////////////////////////////////////////////////////////////////
8319
8320bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8321{
8322 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8323 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8328int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8329{
8330 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8331 return TClinginfo->Next();
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8336void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8337{
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8339 return TClinginfo->New(*fNormalizedCtxt);
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8345{
8346 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8347 return TClinginfo->New(n,*fNormalizedCtxt);
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8352void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8353{
8354 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8355 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8356}
8357
8358////////////////////////////////////////////////////////////////////////////////
8359
8360void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8361{
8362 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8363 return TClinginfo->New(arena,*fNormalizedCtxt);
8364}
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8368Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8369{
8370 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8371 return TClinginfo->Property();
8372}
8373
8374////////////////////////////////////////////////////////////////////////////////
8375
8376int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8377{
8378 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8379 return TClinginfo->Size();
8380}
8381
8382////////////////////////////////////////////////////////////////////////////////
8383
8384Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8385{
8386 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8387 return TClinginfo->Tagnum();
8388}
8389
8390////////////////////////////////////////////////////////////////////////////////
8391
8392const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8393{
8394 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8395 return TClinginfo->FileName();
8396}
8397
8398////////////////////////////////////////////////////////////////////////////////
8399
8400const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8401{
8402 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8403 TTHREAD_TLS_DECL(std::string,output);
8404 TClinginfo->FullName(output,*fNormalizedCtxt);
8405 return output.c_str(); // NOLINT
8406}
8407
8408////////////////////////////////////////////////////////////////////////////////
8409
8410const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8411{
8412 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8413 return TClinginfo->Name();
8414}
8415
8416////////////////////////////////////////////////////////////////////////////////
8417
8418const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8419{
8420 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8421 return TClinginfo->Title();
8422}
8423
8424////////////////////////////////////////////////////////////////////////////////
8425
8426const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8427{
8428 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8429 return TClinginfo->TmpltName();
8430}
8431
8432
8433
8434//______________________________________________________________________________
8435//
8436// BaseClassInfo interface
8437//
8438
8439////////////////////////////////////////////////////////////////////////////////
8440
8441void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8442{
8443 delete(TClingBaseClassInfo*) bcinfo;
8444}
8445
8446////////////////////////////////////////////////////////////////////////////////
8447
8448BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8449{
8451 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8452 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8453}
8454
8455////////////////////////////////////////////////////////////////////////////////
8456
8457BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8458 ClassInfo_t* base) const
8459{
8461 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8462 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8463 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8464}
8465
8466////////////////////////////////////////////////////////////////////////////////
8467
8468int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8469{
8470 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8471 return TClinginfo->Next();
8472}
8473
8474////////////////////////////////////////////////////////////////////////////////
8475
8476int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8477{
8478 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8479 return TClinginfo->Next(onlyDirect);
8480}
8481
8482////////////////////////////////////////////////////////////////////////////////
8483
8484Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8485{
8486 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8487 return TClinginfo->Offset(address, isDerivedObject);
8488}
8489
8490////////////////////////////////////////////////////////////////////////////////
8491
8492Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8493{
8494 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8495 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8496 // Offset to the class itself.
8497 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8498 return 0;
8499 }
8500 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8501}
8502
8503////////////////////////////////////////////////////////////////////////////////
8504
8505Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8506{
8507 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8508 return TClinginfo->Property();
8509}
8510
8511////////////////////////////////////////////////////////////////////////////////
8512
8513ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8514{
8515 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8516 return (ClassInfo_t *)TClinginfo->GetBase();
8517}
8518
8519////////////////////////////////////////////////////////////////////////////////
8520
8521Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8522{
8523 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8524 return TClinginfo->Tagnum();
8525}
8526
8527////////////////////////////////////////////////////////////////////////////////
8528
8529const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8530{
8531 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8532 TTHREAD_TLS_DECL(std::string,output);
8533 TClinginfo->FullName(output,*fNormalizedCtxt);
8534 return output.c_str(); // NOLINT
8535}
8536
8537////////////////////////////////////////////////////////////////////////////////
8538
8539const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8540{
8541 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8542 return TClinginfo->Name();
8543}
8544
8545////////////////////////////////////////////////////////////////////////////////
8546
8547const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8548{
8549 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8550 return TClinginfo->TmpltName();
8551}
8552
8553//______________________________________________________________________________
8554//
8555// DataMemberInfo interface
8556//
8557
8558////////////////////////////////////////////////////////////////////////////////
8559
8560int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8561{
8562 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8563 return TClinginfo->ArrayDim();
8564}
8565
8566////////////////////////////////////////////////////////////////////////////////
8567
8568void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8569{
8570 delete(TClingDataMemberInfo*) dminfo;
8571}
8572
8573////////////////////////////////////////////////////////////////////////////////
8574
8575DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8576{
8578 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8579 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8580}
8581
8582////////////////////////////////////////////////////////////////////////////////
8583
8584DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8585{
8587 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8588 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8589 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8590}
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8594DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8595{
8596 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8597 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8598}
8599
8600////////////////////////////////////////////////////////////////////////////////
8601
8602bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8603{
8604 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8605 return TClinginfo->IsValid();
8606}
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8610int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8611{
8612 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8613 return TClinginfo->MaxIndex(dim);
8614}
8615
8616////////////////////////////////////////////////////////////////////////////////
8617
8618int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8619{
8620 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8621 return TClinginfo->Next();
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625
8626Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8627{
8628 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8629 return TClinginfo->Offset();
8630}
8631
8632////////////////////////////////////////////////////////////////////////////////
8633
8634Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8635{
8636 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8637 return TClinginfo->Property();
8638}
8639
8640////////////////////////////////////////////////////////////////////////////////
8641
8642Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8643{
8644 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8645 return TClinginfo->TypeProperty();
8646}
8647
8648////////////////////////////////////////////////////////////////////////////////
8649
8650int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8651{
8652 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8653 return TClinginfo->TypeSize();
8654}
8655
8656////////////////////////////////////////////////////////////////////////////////
8657
8658const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8659{
8660 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8661 return TClinginfo->TypeName();
8662}
8663
8664////////////////////////////////////////////////////////////////////////////////
8665
8666const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8667{
8668 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8669 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8670}
8671
8672////////////////////////////////////////////////////////////////////////////////
8673
8674const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8675{
8676 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8677 return TClinginfo->Name();
8678}
8679
8680////////////////////////////////////////////////////////////////////////////////
8681
8682const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8683{
8684 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8685 return TClinginfo->Title();
8686}
8687
8688////////////////////////////////////////////////////////////////////////////////
8689
8690const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8691{
8692 TTHREAD_TLS_DECL(std::string,result);
8693
8694 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8695 result = TClinginfo->ValidArrayIndex().str();
8696 return result.c_str(); // NOLINT
8697}
8698
8699////////////////////////////////////////////////////////////////////////////////
8700
8701void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8702{
8703 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8704 ASTContext &C = decl->getASTContext();
8705 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8706}
8707
8708//______________________________________________________________________________
8709//
8710// Function Template interface
8711//
8712
8713////////////////////////////////////////////////////////////////////////////////
8714
8715static void ConstructorName(std::string &name, const clang::Decl *decl,
8716 cling::Interpreter &interp,
8717 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8718{
8719 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8720 if (!td) return;
8721
8722 clang::QualType qualType(td->getTypeForDecl(),0);
8723 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8724 unsigned int level = 0;
8725 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8726 if (name[cursor] == '>') ++level;
8727 else if (name[cursor] == '<' && level) --level;
8728 else if (level == 0 && name[cursor] == ':') {
8729 name.erase(0,cursor+1);
8730 break;
8731 }
8732 }
8733}
8734
8735////////////////////////////////////////////////////////////////////////////////
8736
8737void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8738{
8739 output.clear();
8740
8741 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8742 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8743 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8744 }
8745 if (!FD) {
8746 Error("GetFunctionName", "NULL Decl!");
8747 return;
8748 }
8749
8750 // For using-decls, show "Derived", not "Base", i.e. use the
8751 // name of the decl context of the UsingShadowDecl (aka `decl`)
8752 // not the name of FD's decl context.
8753 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8754 {
8756
8757 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8758 {
8760 output.insert(output.begin(), '~');
8761 } else {
8762 llvm::raw_string_ostream stream(output);
8763 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8764 // Don't trigger fopen of the source file to count lines:
8765 printPolicy.AnonymousTagLocations = false;
8766 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8767 }
8768}
8769
8770////////////////////////////////////////////////////////////////////////////////
8771/// Return a unique identifier of the declaration represented by the
8772/// FuncTempInfo
8773
8775{
8776 return (DeclId_t)info;
8777}
8778
8779////////////////////////////////////////////////////////////////////////////////
8780/// Delete the FuncTempInfo_t
8781
8782void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8783{
8784 // Currently the address of ft_info is actually the decl itself,
8785 // so we have nothing to do.
8786}
8787
8788////////////////////////////////////////////////////////////////////////////////
8789/// Construct a FuncTempInfo_t
8790
8791FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8792{
8793 // Currently the address of ft_info is actually the decl itself,
8794 // so we have nothing to do.
8795
8796 return (FuncTempInfo_t*)const_cast<void*>(declid);
8797}
8798
8799////////////////////////////////////////////////////////////////////////////////
8800/// Construct a FuncTempInfo_t
8801
8802FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8803{
8804 // Currently the address of ft_info is actually the decl itself,
8805 // so we have nothing to do.
8806
8807 return (FuncTempInfo_t*)ft_info;
8808}
8809
8810////////////////////////////////////////////////////////////////////////////////
8811/// Check validity of a FuncTempInfo_t
8812
8813Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8814{
8815 // Currently the address of ft_info is actually the decl itself,
8816 // so we have nothing to do.
8817
8818 return t_info != nullptr;
8819}
8820
8821////////////////////////////////////////////////////////////////////////////////
8822/// Return the maximum number of template arguments of the
8823/// function template described by ft_info.
8824
8825UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8826{
8827 if (!ft_info) return 0;
8828 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8829 return ft->getTemplateParameters()->size();
8830}
8831
8832////////////////////////////////////////////////////////////////////////////////
8833/// Return the number of required template arguments of the
8834/// function template described by ft_info.
8835
8837{
8838 if (!ft_info) return 0;
8839 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8840 return ft->getTemplateParameters()->getMinRequiredArguments();
8841}
8842
8843////////////////////////////////////////////////////////////////////////////////
8844/// Return the property of the function template.
8845
8846Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8847{
8848 if (!ft_info) return 0;
8849
8850 long property = 0L;
8851 property |= kIsCompiled;
8852
8853 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8854
8855 switch (ft->getAccess()) {
8856 case clang::AS_public:
8857 property |= kIsPublic;
8858 break;
8859 case clang::AS_protected:
8860 property |= kIsProtected;
8861 break;
8862 case clang::AS_private:
8863 property |= kIsPrivate;
8864 break;
8865 case clang::AS_none:
8866 if (ft->getDeclContext()->isNamespace())
8868 break;
8869 default:
8870 // IMPOSSIBLE
8871 break;
8872 }
8873
8874 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8875 if (const clang::CXXMethodDecl *md =
8876 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8877 if (md->getMethodQualifiers().hasConst()) {
8878 property |= kIsConstant | kIsConstMethod;
8879 }
8880 if (md->isVirtual()) {
8881 property |= kIsVirtual;
8882 }
8883 if (md->isPure()) {
8884 property |= kIsPureVirtual;
8885 }
8886 if (const clang::CXXConstructorDecl *cd =
8887 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8888 if (cd->isExplicit()) {
8889 property |= kIsExplicit;
8890 }
8891 }
8892 else if (const clang::CXXConversionDecl *cd =
8893 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8894 if (cd->isExplicit()) {
8895 property |= kIsExplicit;
8896 }
8897 }
8898 }
8899 return property;
8900}
8901
8902////////////////////////////////////////////////////////////////////////////////
8903/// Return the property not already defined in Property
8904/// See TDictionary's EFunctionProperty
8905
8906Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8907{
8908 if (!ft_info) return 0;
8909
8910 long property = 0L;
8911 property |= kIsCompiled;
8912
8913 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8914 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8915
8916 if (fd->isOverloadedOperator())
8918 if (llvm::isa<clang::CXXConversionDecl>(fd))
8920 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8922 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8924 if (fd->isInlined())
8926 return property;
8927}
8928
8929////////////////////////////////////////////////////////////////////////////////
8930/// Return the name of this function template.
8931
8932void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8933{
8934 output.Clear();
8935 if (!ft_info) return;
8936 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8937 std::string buf;
8938 GetFunctionName(ft->getTemplatedDecl(), buf);
8939 output = buf;
8940}
8941
8942////////////////////////////////////////////////////////////////////////////////
8943/// Return the comments associates with this function template.
8944
8945void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8946{
8947 output.Clear();
8948 if (!ft_info) return;
8949 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8950
8951 // Iterate over the redeclarations, we can have multiple definitions in the
8952 // redecl chain (came from merging of pcms).
8953 if (const RedeclarableTemplateDecl *AnnotFD
8954 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8955 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8956 output = A->getAnnotation().str();
8957 return;
8958 }
8959 }
8960 if (!ft->isFromASTFile()) {
8961 // Try to get the comment from the header file if present
8962 // but not for decls from AST file, where rootcling would have
8963 // created an annotation
8965 }
8966}
8967
8968
8969//______________________________________________________________________________
8970//
8971// MethodInfo interface
8972//
8973
8974////////////////////////////////////////////////////////////////////////////////
8975/// Interface to cling function
8976
8977void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8978{
8979 delete(TClingMethodInfo*) minfo;
8980}
8981
8982////////////////////////////////////////////////////////////////////////////////
8983
8984void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8985{
8986 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8987 // The next call locks the interpreter mutex.
8988 info->CreateSignature(signature);
8989}
8990
8991////////////////////////////////////////////////////////////////////////////////
8992
8993MethodInfo_t* TCling::MethodInfo_Factory() const
8994{
8996 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8997}
8998
8999////////////////////////////////////////////////////////////////////////////////
9000
9001MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9002{
9004 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9005}
9006
9007////////////////////////////////////////////////////////////////////////////////
9008
9009MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9010{
9011 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9013 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9014}
9015
9016////////////////////////////////////////////////////////////////////////////////
9017
9018MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9019{
9020 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9021}
9022
9023////////////////////////////////////////////////////////////////////////////////
9024
9025void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9026{
9027 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9028 // The next call locks the interpreter mutex.
9029 return info->InterfaceMethod();
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033
9034bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9035{
9036 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9037 return info->IsValid();
9038}
9039
9040////////////////////////////////////////////////////////////////////////////////
9041
9042int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9043{
9044 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9045 return info->NArg();
9046}
9047
9048////////////////////////////////////////////////////////////////////////////////
9049
9050int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9051{
9052 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9053 return info->NDefaultArg();
9054}
9055
9056////////////////////////////////////////////////////////////////////////////////
9057
9058int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9059{
9060 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9061 return info->Next();
9062}
9063
9064////////////////////////////////////////////////////////////////////////////////
9065
9066Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9067{
9068 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9069 // The next call locks the interpreter mutex.
9070 return info->Property();
9071}
9072
9073////////////////////////////////////////////////////////////////////////////////
9074
9076{
9077 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9078 // The next call locks the interpreter mutex.
9079 return info->ExtraProperty();
9080}
9081
9082////////////////////////////////////////////////////////////////////////////////
9083
9084TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9085{
9086 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9087 // The next call locks the interpreter mutex.
9088 return (TypeInfo_t*)info->Type();
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092
9093const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9094{
9095 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9096 TTHREAD_TLS_DECL(TString, mangled_name);
9097 // The next call locks the interpreter mutex.
9098 mangled_name = info->GetMangledName();
9099 return mangled_name;
9100}
9101
9102////////////////////////////////////////////////////////////////////////////////
9103
9104const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9105{
9106 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9107 // The next call locks the interpreter mutex.
9108 return info->GetPrototype();
9109}
9110
9111////////////////////////////////////////////////////////////////////////////////
9112
9113const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9114{
9115 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9116 // The next call locks the interpreter mutex.
9117 return info->Name();
9118}
9119
9120////////////////////////////////////////////////////////////////////////////////
9121
9122const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9123{
9124 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9125 // The next call locks the interpreter mutex.
9126 return info->TypeName();
9127}
9128
9129////////////////////////////////////////////////////////////////////////////////
9130
9131std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9132{
9133 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9134 // The next part locks the interpreter mutex.
9135 if (info && info->IsValid())
9136 return info->Type()->NormalizedName(*fNormalizedCtxt);
9137 else
9138 return "";
9139}
9140
9141////////////////////////////////////////////////////////////////////////////////
9142
9143const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9144{
9145 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9146 // The next call locks the interpreter mutex.
9147 return info->Title();
9148}
9149
9150////////////////////////////////////////////////////////////////////////////////
9151
9153{
9154 if (func) {
9155 return MethodInfo_MethodCallReturnType(func->fInfo);
9156 } else {
9157 return EReturnType::kOther;
9158 }
9159}
9160
9161////////////////////////////////////////////////////////////////////////////////
9162
9164{
9165 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9166 if (info && info->IsValid()) {
9167 TClingTypeInfo *typeinfo = info->Type();
9168 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9169 if (QT->isEnumeralType()) {
9170 return EReturnType::kLong;
9171 } else if (QT->isPointerType()) {
9172 // Look for char*
9173 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9174 if ( QT->isCharType() ) {
9175 return EReturnType::kString;
9176 } else {
9177 return EReturnType::kOther;
9178 }
9179 } else if ( QT->isFloatingType() ) {
9180 int sz = typeinfo->Size();
9181 if (sz == 4 || sz == 8) {
9182 // Support only float and double.
9183 return EReturnType::kDouble;
9184 } else {
9185 return EReturnType::kOther;
9186 }
9187 } else if ( QT->isIntegerType() ) {
9188 int sz = typeinfo->Size();
9189 if (sz <= 8) {
9190 // Support only up to long long ... but
9191 // FIXME the TMethodCall::Execute only
9192 // return long (4 bytes) ...
9193 // The v5 implementation of TMethodCall::ReturnType
9194 // was not making the distinction so we let it go
9195 // as is for now, but we really need to upgrade
9196 // TMethodCall::Execute ...
9197 return EReturnType::kLong;
9198 } else {
9199 return EReturnType::kOther;
9200 }
9201 } else {
9202 return EReturnType::kOther;
9203 }
9204 } else {
9205 return EReturnType::kOther;
9206 }
9207}
9208
9209//______________________________________________________________________________
9210//
9211// MethodArgInfo interface
9212//
9213
9214////////////////////////////////////////////////////////////////////////////////
9215
9216void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9217{
9218 delete(TClingMethodArgInfo*) marginfo;
9219}
9220
9221////////////////////////////////////////////////////////////////////////////////
9222
9223MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9224{
9226 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9227}
9228
9229////////////////////////////////////////////////////////////////////////////////
9230
9231MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9232{
9234 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9235}
9236
9237////////////////////////////////////////////////////////////////////////////////
9238
9239MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9240{
9241 return (MethodArgInfo_t*)
9243}
9244
9245////////////////////////////////////////////////////////////////////////////////
9246
9247bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9248{
9249 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9250 return info->IsValid();
9251}
9252
9253////////////////////////////////////////////////////////////////////////////////
9254
9255int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9256{
9257 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9258 return info->Next();
9259}
9260
9261////////////////////////////////////////////////////////////////////////////////
9262
9263Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9264{
9265 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9266 return info->Property();
9267}
9268
9269////////////////////////////////////////////////////////////////////////////////
9270
9271const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9272{
9273 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9274 return info->DefaultValue();
9275}
9276
9277////////////////////////////////////////////////////////////////////////////////
9278
9279const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9280{
9281 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9282 return info->Name();
9283}
9284
9285////////////////////////////////////////////////////////////////////////////////
9286
9287const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9288{
9289 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9290 return info->TypeName();
9291}
9292
9293////////////////////////////////////////////////////////////////////////////////
9294
9295std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9296{
9297 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9298 return info->Type()->NormalizedName(*fNormalizedCtxt);
9299}
9300
9301////////////////////////////////////////////////////////////////////////////////
9302
9303TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9304{
9305 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9306 return (TypeInfo_t*) info->Type();
9307}
9308
9309//______________________________________________________________________________
9310//
9311// TypeInfo interface
9312//
9313
9314////////////////////////////////////////////////////////////////////////////////
9315
9316void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9317{
9318 delete (TClingTypeInfo*) tinfo;
9319}
9320
9321////////////////////////////////////////////////////////////////////////////////
9322
9323TypeInfo_t* TCling::TypeInfo_Factory() const
9324{
9326 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9327}
9328
9329////////////////////////////////////////////////////////////////////////////////
9330
9331TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9332{
9334 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9335}
9336
9337////////////////////////////////////////////////////////////////////////////////
9338
9339TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9340{
9341 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9342}
9343
9344////////////////////////////////////////////////////////////////////////////////
9345
9346void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9347{
9349 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9350 TClinginfo->Init(name);
9351}
9352
9353////////////////////////////////////////////////////////////////////////////////
9354
9355bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9356{
9357 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9358 return TClinginfo->IsValid();
9359}
9360
9361////////////////////////////////////////////////////////////////////////////////
9362
9363const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9364{
9365 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9366 return TClinginfo->Name();
9367}
9368
9369////////////////////////////////////////////////////////////////////////////////
9370
9371Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9372{
9373 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9374 return TClinginfo->Property();
9375}
9376
9377////////////////////////////////////////////////////////////////////////////////
9378
9379int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9380{
9381 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9382 return TClinginfo->RefType();
9383}
9384
9385////////////////////////////////////////////////////////////////////////////////
9386
9387int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9388{
9389 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9390 return TClinginfo->Size();
9391}
9392
9393////////////////////////////////////////////////////////////////////////////////
9394
9395const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9396{
9397 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9398 return TClinginfo->TrueName(*fNormalizedCtxt);
9399}
9400
9401////////////////////////////////////////////////////////////////////////////////
9402
9403void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9404{
9405 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9406 return TClinginfo->QualTypePtr();
9407}
9408
9409
9410//______________________________________________________________________________
9411//
9412// TypedefInfo interface
9413//
9414
9415////////////////////////////////////////////////////////////////////////////////
9416
9417void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9418{
9419 delete(TClingTypedefInfo*) tinfo;
9420}
9421
9422////////////////////////////////////////////////////////////////////////////////
9423
9424TypedefInfo_t* TCling::TypedefInfo_Factory() const
9425{
9427 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9428}
9429
9430////////////////////////////////////////////////////////////////////////////////
9431
9432TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9433{
9435 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9436}
9437
9438////////////////////////////////////////////////////////////////////////////////
9439
9440TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9441{
9442 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9443}
9444
9445////////////////////////////////////////////////////////////////////////////////
9446
9447void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9448 const char* name) const
9449{
9451 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9452 TClinginfo->Init(name);
9453}
9454
9455////////////////////////////////////////////////////////////////////////////////
9456
9457bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9458{
9459 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9460 return TClinginfo->IsValid();
9461}
9462
9463////////////////////////////////////////////////////////////////////////////////
9464
9465Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9466{
9467 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9468 return TClinginfo->Next();
9469}
9470
9471////////////////////////////////////////////////////////////////////////////////
9472
9473Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9474{
9475 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9476 return TClinginfo->Property();
9477}
9478
9479////////////////////////////////////////////////////////////////////////////////
9480
9481int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9482{
9483 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9484 return TClinginfo->Size();
9485}
9486
9487////////////////////////////////////////////////////////////////////////////////
9488
9489const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9490{
9491 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9492 return TClinginfo->TrueName(*fNormalizedCtxt);
9493}
9494
9495////////////////////////////////////////////////////////////////////////////////
9496
9497const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9498{
9499 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9500 return TClinginfo->Name();
9501}
9502
9503////////////////////////////////////////////////////////////////////////////////
9504
9505const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9506{
9507 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9508 return TClinginfo->Title();
9509}
9510
9511////////////////////////////////////////////////////////////////////////////////
9512
9513bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9514{
9515 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9516 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9517 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9518}
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9522bool TCling::IsIntegerType(const void * QualTypePtr) const
9523{
9524 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9525 return QT->hasIntegerRepresentation();
9526}
9527
9528////////////////////////////////////////////////////////////////////////////////
9529
9530bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9531{
9532 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9533 return QT->hasSignedIntegerRepresentation();
9534}
9535
9536////////////////////////////////////////////////////////////////////////////////
9537
9538bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9539{
9540 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9541 return QT->hasUnsignedIntegerRepresentation();
9542}
9543
9544////////////////////////////////////////////////////////////////////////////////
9545
9546bool TCling::IsFloatingType(const void * QualTypePtr) const
9547{
9548 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9549 return QT->hasFloatingRepresentation();
9550}
9551
9552////////////////////////////////////////////////////////////////////////////////
9553
9554bool TCling::IsPointerType(const void * QualTypePtr) const
9555{
9556 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9557 return QT->hasPointerRepresentation();
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561
9562bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9563{
9564 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9565 return QT->isVoidPointerType();
9566}
9567
9568////////////////////////////////////////////////////////////////////////////////
9569
9571{
9572 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9573 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9574}
9575
9576////////////////////////////////////////////////////////////////////////////////
9577
9579{
9580 if (!fInitialMutex) {
9582 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9583 }
9585 }
9586 // We will "forget" this lock once we backed out of all interpreter frames.
9587 // Here we are entering one, so ++.
9589}
9590
9591////////////////////////////////////////////////////////////////////////////////
9592
9594{
9595 if (!fInitialMutex)
9596 return;
9597 if (fInitialMutex.fRecurseCount == 0) {
9598 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9599 }
9600 else if (--fInitialMutex.fRecurseCount == 0) {
9601 // We have returned from all interpreter frames. Reset the initial lock state.
9602 fInitialMutex.fState.reset();
9603 }
9604}
9605
9606////////////////////////////////////////////////////////////////////////////////
9607/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9608
9610{
9611 if (gInterpreterMutex) {
9612 if (delta) {
9613 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9614 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9615 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9616 // Now that we have the lock, update the global
9617 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9618 std::swap(fInitialMutex, typedDelta->fInitialState);
9619 } else {
9620 // This case happens when EnableThreadSafety is first called from
9621 // the interpreter function we just handled.
9622 // Since thread safety was not enabled at the time we rewound, there was
9623 // no lock taken and even-though we should be locking the rest of this
9624 // interpreter handling/modifying code (since there might be threads in
9625 // flight), we can't because there would not be any lock guard to release the
9626 // locks
9628 Error("ApplyToInterpreterMutex",
9629 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9630 "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.");
9631 }
9632 }
9633}
9634
9635////////////////////////////////////////////////////////////////////////////////
9636/// Reset the interpreter lock to the state it had before interpreter-related
9637/// calls happened.
9638
9640{
9641 if (fInitialMutex) {
9642 // Need to start a new recurse count.
9643 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9644 std::swap(uniqueP->fInitialState, fInitialMutex);
9645 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9646 return uniqueP.release();
9647 }
9649 return nullptr;
9650}
#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 e(i)
Definition RSha256.hxx:103
RooAbsReal & function()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1308
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7229
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:574
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:901
R__EXTERN int optind
Definition TCling.cxx:317
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:368
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:569
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:557
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:333
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:224
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3905
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:351
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1948
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3129
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition TCling.cxx:3947
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:633
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1089
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:910
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:1074
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:379
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1673
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:628
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:221
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:699
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1088
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:251
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:593
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:564
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:604
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3923
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:588
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:389
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:215
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:644
#define R__DLLEXPORT
Definition TCling.cxx:151
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:360
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:233
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:623
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1039
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1192
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8715
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:326
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:2432
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:7138
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:236
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:680
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1973
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:608
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:6974
const char * fantomline
Definition TCling.cxx:848
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:583
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6313
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5493
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:218
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:600
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:1061
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:639
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:616
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7250
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:651
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
#define gDirectory
Definition TDirectory.h:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
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:244
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
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 data
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:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:595
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
@ kReadPermission
Definition TSystem.h:45
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:116
R__EXTERN TSystem * gSystem
Definition TSystem.h:555
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17536
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static 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:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3439
EState GetState() const
Definition TClass.h:486
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2886
EState fState
cached of the streaming method to use
Definition TClass.h:275
std::atomic< TList * > fBase
Definition TClass.h:202
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:222
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3798
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:4915
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:536
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2205
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:206
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3398
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5959
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5749
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5704
@ kLoading
Definition TClass.h:330
@ kUnloading
Definition TClass.h:330
TObjArray * fStreamerInfo
Definition TClass.h:199
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
ClassInfo_t * GetClassInfo() const
Definition TClass.h:431
ClassInfo_t * fClassInfo
Definition TClass.h:223
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4215
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1820
@ kInterpreted
Definition TClass.h:127
@ kHasTClassInit
Definition TClass.h:128
@ kEmulated
Definition TClass.h:126
@ kForwardDeclared
Definition TClass.h:125
@ kNamespaceForMeta
Definition TClass.h:132
Version_t GetClassVersion() const
Definition TClass.h:418
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:257
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3463
@ kIsTObject
Definition TClass.h:100
@ kIsEmulation
Definition TClass.h:102
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:2968
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void ExecWithReturn(void *address, void *ret=nullptr)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
bool IsValid() const
Longptr_t ExecInt(void *address)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
void IgnoreExtraArgs(bool ignore)
void SetArg(T arg)
long long ExecInt64(void *address)
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * 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
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1015
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1023
std::string fContent
Definition TCling.h:619
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:6185
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9271
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8278
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9363
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9025
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4373
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3885
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9457
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6246
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7916
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:3648
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6549
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7433
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7842
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9084
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7819
Bool_t fLockProcessLine
Definition TCling.h:127
int LoadFile(const char *path) const final
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7476
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3724
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8701
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:496
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:6869
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9066
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4420
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8312
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8634
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7561
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:149
void CreateListOfDataMembers(TClass *cl) const final
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4467
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3769
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8304
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6743
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9379
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4349
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8191
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9113
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8448
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4018
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7491
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7266
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9163
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7690
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3560
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9034
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8791
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9323
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7530
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6854
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7654
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7639
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3348
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9505
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:8041
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5636
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:6504
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9570
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1820
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4485
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1627
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7743
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2657
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8468
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6616
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7893
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7877
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7942
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5444
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3172
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3872
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7908
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9609
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6572
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:4704
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:8107
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3138
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:7455
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8560
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9303
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8594
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3665
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:5509
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8328
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7582
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9247
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9387
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3783
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7463
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7618
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:8825
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:5136
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9424
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9562
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2462
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8376
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9287
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:644
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5384
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8618
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9497
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8441
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9075
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3552
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8802
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8610
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8813
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:2671
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8263
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3683
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8658
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4931
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:7998
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8088
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9639
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9279
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3147
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9447
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8682
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7861
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3085
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:7512
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:7333
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7900
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9538
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9440
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:5029
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:2402
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9295
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:4813
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9263
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9481
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7850
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:5181
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:634
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6723
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3515
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9465
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:4988
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9346
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7572
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8650
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8418
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8674
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5459
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9530
void ForgetMutexState() final
Definition TCling.cxx:9593
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9058
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8152
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:8977
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9216
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8575
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8183
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:6091
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5979
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8245
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8513
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7869
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8368
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8492
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:421
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5366
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7319
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7396
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6929
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8846
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9395
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:5997
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7663
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6967
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9255
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9578
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9371
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9104
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:8836
std::vector< cling::Value > * fTemporaries
Definition TCling.h:133
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:2019
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6137
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:8984
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4327
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6952
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:2393
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8602
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8271
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9050
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4476
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5906
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:7591
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9093
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9522
std::hash< std::string > fStringHashFunction
Definition TCling.h:124
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:591
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:5091
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8336
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7387
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8737
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4501
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7378
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9239
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8484
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE) final
Checks if an entity with the specified name is defined in Cling.
Definition TCling.cxx:4155
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7425
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3415
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9316
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9042
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4922
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9152
void ProcessClassesToUpdate()
Definition TCling.cxx:1989
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:5114
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:4943
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9143
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8547
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:3098
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8529
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8006
int UnloadFile(const char *path) const final
Definition TCling.cxx:7624
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7826
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9554
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9546
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8906
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7925
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8539
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8690
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4522
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1032
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4853
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5214
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8296
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8384
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8505
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8014
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4456
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8392
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8945
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8426
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3859
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1705
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6608
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:3740
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7646
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:3754
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7499
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3585
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5918
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3892
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8568
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:5397
void * fPrevLoadedDynLibInfo
Definition TCling.h:137
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition TCling.cxx:4494
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:2693
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6059
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9018
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7934
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9223
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6717
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:5010
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8160
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8287
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8782
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:5158
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3798
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:7072
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8626
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7885
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:8993
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8642
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3077
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2451
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:7522
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2367
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9417
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3708
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9489
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7543
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8400
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:6362
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9122
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7950
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7347
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6827
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6659
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9513
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1645
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:8221
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:4752
void * fAutoLoadCallBack
Definition TCling.h:147
void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const final
Return the name of this function template.
Definition TCling.cxx:8932
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9355
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1915
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9131
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8410
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4532
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8229
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3121
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9339
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9403
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8237
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8175
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:8666
virtual void ShutDown() final
Definition TCling.cxx:1664
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3899
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9473
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1687
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:3569
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:4970
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6732
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5722
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8521
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6959
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
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:212
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h:63
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:175
DeclId_t GetDeclId() const
Definition TEnum.cxx:146
@ kNone
Definition TEnum.h:48
@ kAutoload
Definition TEnum.h:49
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
THashList * GetTable() const
Definition TEnv.h:140
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:793
virtual void SetRcName(const char *name)
Definition TEnv.h:145
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:592
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:547
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:53
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * Remove(TObject *obj) 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 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...
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:307
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
TNamed()
Definition TNamed.h:36
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Clear(Option_t *option="") override
Remove all objects from the array.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
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
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
virtual TClass * IsA() const
Definition TObject.h:245
void MakeZombie()
Definition TObject.h:53
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
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:2995
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2734
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2905
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3005
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2915
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:2984
Sequenceable collection abstract base class.
Int_t LastIndex() const
void Add(TObject *obj) override
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:931
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:572
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:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1665
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3973
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4258
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1071
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1538
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2489
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1795
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2034
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition TSystem.cxx:2836
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:871
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1649
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:887
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2020
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TLine * line
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
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 mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
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.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:188
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:183
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:184
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:208
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:125
Long_t fMemVirtual
Definition TSystem.h:194
Long_t fMemResident
Definition TSystem.h:193
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::vector< std::string > fElements
Definition TClassEdit.h:141
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:157
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:162
A read-only memory range which we do not control.
Definition TMemFile.h:23
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static void output()