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) {
4117 } else {
4118// if (TClassEdit::IsSTLCont(cl->GetName()) {
4119// There will be an emulated collection proxy, is that the same?
4120// cl->fState = TClass::kEmulated;
4121// } else {
4122 if (cl->fStreamerInfo->GetEntries() != 0) {
4124 } else {
4126 }
4127// }
4128 }
4129 }
4130 if (cl->fClassInfo) {
4131 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4132 }
4133}
4134
4135////////////////////////////////////////////////////////////////////////////////
4136/// Checks if an entity with the specified name is defined in Cling.
4137/// Returns kUnknown if the entity is not defined.
4138/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4139/// Returns kKnown if the entity is defined.
4140///
4141/// By default, structs, namespaces, classes, enums and unions are looked for.
4142/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4143/// namespaces only are considered. I.e. if the name is an enum or a union,
4144/// the returned value is false.
4145///
4146/// In the case where the class is not loaded and belongs to a namespace
4147/// or is nested, looking for the full class name is outputting a lots of
4148/// (expected) error messages. Currently the only way to avoid this is to
4149/// specifically check that each level of nesting is already loaded.
4150/// In case of templates the idea is that everything between the outer
4151/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4152
4154TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4155{
4157 static const char *anonEnum = "anonymous enum ";
4158 static const int cmplen = strlen(anonEnum);
4159
4160 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4161 return kUnknown;
4162 }
4163
4164 // Do not turn on the AutoLoading if it is globally off.
4165 autoload = autoload && IsClassAutoLoadingEnabled();
4166
4167 // Avoid the double search below in case the name is a fundamental type
4168 // or typedef to a fundamental type.
4169 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4170 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4171
4172 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4173 && fundType->GetType() > 0) {
4174 // Fundamental type, no a class.
4175 return kUnknown;
4176 }
4177
4178 // Migrated from within TClass::GetClass
4179 // If we want to know if a class or a namespace with this name exists in the
4180 // interpreter and this is an enum in the type system, before or after loading
4181 // according to the autoload function argument, return kUnknown.
4182 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4183 return kUnknown;
4184
4185 const char *classname = name;
4186
4187 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4188 class MaybeSuspendAutoLoadParse {
4189 int fStoreAutoLoad = 0;
4190 int fStoreAutoParse = 0;
4191 bool fSuspendedAutoParse = false;
4192 public:
4193 MaybeSuspendAutoLoadParse(int autoload) {
4194 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4195 }
4196
4197 void SuspendAutoParsing() {
4198 fSuspendedAutoParse = true;
4199 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4200 }
4201
4202 ~MaybeSuspendAutoLoadParse() {
4203 if (fSuspendedAutoParse)
4204 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4205 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4206 }
4207 };
4208
4209 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4210 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4211 autoLoadParseRAII.SuspendAutoParsing();
4212
4213 // First we want to check whether the decl exist, but _without_
4214 // generating any template instantiation. However, the lookup
4215 // still will create a forward declaration of the class template instance
4216 // if it exist. In this case, the return value of findScope will still
4217 // be zero but the type will be initialized.
4218 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4219 // this forward declaration.
4220 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4221 const clang::Type *type = nullptr;
4222 const clang::Decl *decl
4223 = lh.findScope(classname,
4224 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4225 : cling::LookupHelper::NoDiagnostics,
4226 &type, /* intantiateTemplate= */ false );
4227 if (!decl) {
4228 std::string buf = TClassEdit::InsertStd(classname);
4229 decl = lh.findScope(buf,
4230 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4231 : cling::LookupHelper::NoDiagnostics,
4232 &type,false);
4233 }
4234
4235 if (type) {
4236 // If decl==0 and the type is valid, then we have a forward declaration.
4237 if (!decl) {
4238 // If we have a forward declaration for a class template instantiation,
4239 // we want to ignore it if it was produced/induced by the call to
4240 // findScope, however we can not distinguish those from the
4241 // instantiation induce by 'soft' use (and thus also induce by the
4242 // same underlying code paths)
4243 // ['soft' use = use not requiring a complete definition]
4244 // So to reduce the amount of disruption to the existing code we
4245 // would just ignore those for STL collection, for which we really
4246 // need to have the compiled collection proxy (and thus the TClass
4247 // bootstrap).
4248 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4249 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4250 (type->getAsCXXRecordDecl());
4251 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4252 // Since the point of instantiation is invalid, we 'guess' that
4253 // the 'instantiation' of the forwarded type appended in
4254 // findscope.
4255 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4256 // For STL Collection we return kUnknown.
4257 return kUnknown;
4258 }
4259 }
4260 }
4262 if (!tci.IsValid()) {
4263 return kUnknown;
4264 }
4265 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4267
4268 if (tci.Property() & propertiesMask) {
4269 bool hasClassDefInline = false;
4270 if (isClassOrNamespaceOnly) {
4271 // We do not need to check for ClassDefInline when this is called from
4272 // TClass::Init, we only do it for the call from TClass::GetClass.
4273 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4274 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4275
4276 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4277 int lineNumber = 0;
4278 bool success = false;
4279 std::tie(success, lineNumber) =
4280 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4281 hasClassDefInline = success && (lineNumber == -1);
4282 }
4283 }
4284
4285 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4286 // , hasClassDefInline);
4287
4288 // We are now sure that the entry is not in fact an autoload entry.
4289 if (hasClassDefInline)
4290 return kWithClassDefInline;
4291 else
4292 return kKnown;
4293 } else {
4294 // We are now sure that the entry is not in fact an autoload entry.
4295 return kUnknown;
4296 }
4297 }
4298
4299 if (decl)
4300 return kKnown;
4301 else
4302 return kUnknown;
4303
4304 // Setting up iterator part of TClingTypedefInfo is too slow.
4305 // Copy the lookup code instead:
4306 /*
4307 TClingTypedefInfo t(fInterpreter, name);
4308 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4309 delete[] classname;
4310 return kTRUE;
4311 }
4312 */
4313
4314// const clang::Decl *decl = lh.findScope(name);
4315// if (!decl) {
4316// std::string buf = TClassEdit::InsertStd(name);
4317// decl = lh.findScope(buf);
4318// }
4319
4320// return (decl);
4321}
4322
4323////////////////////////////////////////////////////////////////////////////////
4324/// Return true if there is a class template by the given name ...
4325
4327{
4328 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4329 // Interpreter transaction ahead, needs locking
4331 const clang::Decl *decl
4332 = lh.findClassTemplate(name,
4333 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4334 : cling::LookupHelper::NoDiagnostics);
4335 if (!decl) {
4336 std::string strname = "std::";
4337 strname += name;
4338 decl = lh.findClassTemplate(strname,
4339 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4340 : cling::LookupHelper::NoDiagnostics);
4341 }
4342 return nullptr != decl;
4343}
4344
4345////////////////////////////////////////////////////////////////////////////////
4346/// Create list of pointers to base class(es) for TClass cl.
4347
4349{
4351 if (cl->fBase) {
4352 return;
4353 }
4355 if (!tci) return;
4357 TList *listOfBase = new TList;
4358 while (t.Next()) {
4359 // if name cannot be obtained no use to put in list
4360 if (t.IsValid() && t.Name()) {
4362 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4363 }
4364 }
4365 // Now that is complete, publish it.
4366 cl->fBase = listOfBase;
4367}
4368
4369////////////////////////////////////////////////////////////////////////////////
4370/// Create list of pointers to enums for TClass cl.
4371
4372void TCling::LoadEnums(TListOfEnums& enumList) const
4373{
4375
4376 const Decl * D;
4377 TClass* cl = enumList.GetClass();
4378 if (cl) {
4379 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4380 }
4381 else {
4382 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4383 }
4384 // Iterate on the decl of the class and get the enums.
4385 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4386 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4387 // Collect all contexts of the namespace.
4388 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4389 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4390 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4391 declIter != declEnd; ++declIter) {
4392 // Iterate on all decls for each context.
4393 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4394 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4395 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4396 // Get name of the enum type.
4397 std::string buf;
4398 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4399 llvm::raw_string_ostream stream(buf);
4400 // Don't trigger fopen of the source file to count lines:
4401 Policy.AnonymousTagLocations = false;
4402 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4403 stream.flush();
4404 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4405 if (!buf.empty()) {
4406 const char* name = buf.c_str();
4407 // Add the enum to the list of loaded enums.
4408 enumList.Get(ED, name);
4409 }
4410 }
4411 }
4412 }
4413 }
4414}
4415
4416////////////////////////////////////////////////////////////////////////////////
4417/// Create list of pointers to function templates for TClass cl.
4418
4420{
4422
4423 const Decl * D;
4424 TListOfFunctionTemplates* funcTempList;
4425 if (cl) {
4426 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4427 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4428 }
4429 else {
4430 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4431 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4432 }
4433 // Iterate on the decl of the class and get the enums.
4434 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4435 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4436 // Collect all contexts of the namespace.
4437 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4438 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4439 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4440 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4441 // Iterate on all decls for each context.
4442 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4443 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4444 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4445 funcTempList->Get(FTD);
4446 }
4447 }
4448 }
4449 }
4450}
4451
4452////////////////////////////////////////////////////////////////////////////////
4453/// Get the scopes representing using declarations of namespace
4454
4455std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4456{
4458 return ci->GetUsingNamespaces();
4459}
4460
4461////////////////////////////////////////////////////////////////////////////////
4462/// Create list of pointers to data members for TClass cl.
4463/// This is now a nop. The creation and updating is handled in
4464/// TListOfDataMembers.
4465
4467{
4468}
4469
4470////////////////////////////////////////////////////////////////////////////////
4471/// Create list of pointers to methods for TClass cl.
4472/// This is now a nop. The creation and updating is handled in
4473/// TListOfFunctions.
4474
4476{
4477}
4478
4479////////////////////////////////////////////////////////////////////////////////
4480/// Update the list of pointers to method for TClass cl
4481/// This is now a nop. The creation and updating is handled in
4482/// TListOfFunctions.
4483
4485{
4486}
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Update the list of pointers to data members for TClass cl
4490/// This is now a nop. The creation and updating is handled in
4491/// TListOfDataMembers.
4492
4494{
4495}
4496
4497////////////////////////////////////////////////////////////////////////////////
4498/// Create list of pointers to method arguments for TMethod m.
4499
4501{
4503 if (m->fMethodArgs) {
4504 return;
4505 }
4506 TList *arglist = new TList;
4508 while (t.Next()) {
4509 if (t.IsValid()) {
4511 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4512 }
4513 }
4514 m->fMethodArgs = arglist;
4515}
4516
4517////////////////////////////////////////////////////////////////////////////////
4518/// Return whether we are waiting for more input either because the collected
4519/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4520
4522{
4523 return fMetaProcessor->awaitingMoreInput();
4524}
4525
4526////////////////////////////////////////////////////////////////////////////////
4527/// Generate a TClass for the given class.
4528/// Since the caller has already check the ClassInfo, let it give use the
4529/// result (via the value of emulation) rather than recalculate it.
4530
4531TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4532{
4533// For now the following line would lead to the (unwanted) instantiation
4534// of class template. This could/would need to be resurrected only if
4535// we re-introduce so sort of automatic instantiation. However this would
4536// have to include carefull look at the template parameter to avoid
4537// creating instance we can not really use (if the parameter are only forward
4538// declaration or do not have all the necessary interfaces).
4539
4540 // TClingClassInfo tci(fInterpreter, classname);
4541 // if (1 || !tci.IsValid()) {
4542
4543 Version_t version = 1;
4544 if (TClassEdit::IsSTLCont(classname)) {
4545 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4546 }
4548 TClass *cl = new TClass(classname, version, silent);
4549 if (!emulation) {
4550 // Set the class version if the class is versioned.
4551 // Note that we cannot just call CLASS::Class_Version() as we might not have
4552 // an execution engine (when invoked from rootcling).
4553
4554 // Do not call cl->GetClassVersion(), it has side effects!
4555 Version_t oldvers = cl->fClassVersion;
4556 if (oldvers == version && cl->GetClassInfo()) {
4557 // We have a version and it might need an update.
4559 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4560 // Namespaces don't have class versions.
4561 return cl;
4562 }
4563 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4566 if (!mi.IsValid()) {
4567 if (cl->TestBit(TClass::kIsTObject)) {
4568 Error("GenerateTClass",
4569 "Cannot find %s::Class_Version()! Class version might be wrong.",
4570 cl->GetName());
4571 }
4572 return cl;
4573 }
4574 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4575 *fInterpreter);
4576 if (newvers == -1) {
4577 // Didn't manage to determine the class version from the AST.
4578 // Use runtime instead.
4579 if ((mi.Property() & kIsStatic)
4580 && !fInterpreter->isInSyntaxOnlyMode()) {
4581 // This better be a static function.
4583 callfunc.SetFunc(&mi);
4584 newvers = callfunc.ExecInt(nullptr);
4585 } else {
4586 Error("GenerateTClass",
4587 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4588 cl->GetName());
4589 }
4590 }
4591 if (newvers != oldvers) {
4592 cl->fClassVersion = newvers;
4593 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4594 }
4595 }
4596 }
4597
4598 return cl;
4599
4600// } else {
4601// return GenerateTClass(&tci,silent);
4602// }
4603}
4604
4605#if 0
4606////////////////////////////////////////////////////////////////////////////////
4607
4608static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4609{
4610 includes += info->FileName();
4611
4612 const clang::ClassTemplateSpecializationDecl *templateCl
4613 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4614 if (templateCl) {
4615 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4616 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4617 if (arg.getKind() == clang::TemplateArgument::Type) {
4618 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4619
4620 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4621 // We really need a header file.
4622 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4623 if (argdecl) {
4624 includes += ";";
4625 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4626 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4627 } else {
4628 std::string Result;
4629 llvm::raw_string_ostream OS(Result);
4630 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4631 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4632 }
4633 }
4634 }
4635 }
4636 }
4637}
4638#endif
4639
4640////////////////////////////////////////////////////////////////////////////////
4641/// Generate a TClass for the given class.
4642
4643TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4644{
4645 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4646 if (!info || !info->IsValid()) {
4647 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4648 return nullptr;
4649 }
4650 // We are in the case where we have AST nodes for this class.
4651 TClass *cl = nullptr;
4652 std::string classname;
4653 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4654 if (TClassEdit::IsSTLCont(classname)) {
4655#if 0
4656 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4657 // We need to build up the list of required headers, by
4658 // looking at each template arguments.
4659 TString includes;
4660 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4661
4662 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4663 // 0 means success.
4664 cl = TClass::LoadClass(classnam.c_str(), silent);
4665 if (cl == 0) {
4666 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4667 }
4668 }
4669#endif
4670 if (cl == nullptr) {
4671 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4672 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4673 }
4674 } else {
4675 // For regular class, just create a TClass on the fly ...
4676 // Not quite useful yet, but that what CINT used to do anyway.
4677 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4678 }
4679 // Add the new TClass to the map of declid and TClass*.
4680 if (cl) {
4682 }
4683 return cl;
4684}
4685
4686////////////////////////////////////////////////////////////////////////////////
4687/// Generate the dictionary for the C++ classes listed in the first
4688/// argument (in a semi-colon separated list).
4689/// 'includes' contains a semi-colon separated list of file to
4690/// `#include` in the dictionary.
4691/// For example:
4692/// ~~~ {.cpp}
4693/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4694/// ~~~
4695/// or
4696/// ~~~ {.cpp}
4697/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4698/// ~~~
4699
4700Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4701{
4702 if (classes == nullptr || classes[0] == 0) {
4703 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4704 return 0;
4705 }
4706 // Split the input list
4707 std::vector<std::string> listClasses;
4708 for (
4709 const char* current = classes, *prev = classes;
4710 *current != 0;
4711 ++current
4712 ) {
4713 if (*current == ';') {
4714 listClasses.push_back(std::string(prev, current - prev));
4715 prev = current + 1;
4716 }
4717 else if (*(current + 1) == 0) {
4718 listClasses.push_back(std::string(prev, current + 1 - prev));
4719 prev = current + 1;
4720 }
4721 }
4722 std::vector<std::string> listIncludes;
4723 if (!includes)
4724 includes = "";
4725 for (
4726 const char* current = includes, *prev = includes;
4727 *current != 0;
4728 ++current
4729 ) {
4730 if (*current == ';') {
4731 listIncludes.push_back(std::string(prev, current - prev));
4732 prev = current + 1;
4733 }
4734 else if (*(current + 1) == 0) {
4735 listIncludes.push_back(std::string(prev, current + 1 - prev));
4736 prev = current + 1;
4737 }
4738 }
4739 // Generate the temporary dictionary file
4740 return !TCling_GenerateDictionary(listClasses, listIncludes,
4741 std::vector<std::string>(), std::vector<std::string>());
4742}
4743
4744////////////////////////////////////////////////////////////////////////////////
4745/// Return pointer to cling Decl of global/static variable that is located
4746/// at the address given by addr.
4747
4748TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4749{
4751 DeclId_t d;
4752 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4753
4754 // Could trigger deserialization of decls.
4755 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4756
4757 if (cl) {
4758 d = cl->GetDataMember(name);
4759 // We check if the decl of the data member has an annotation which indicates
4760 // an ioname.
4761 // In case this is true, if the name requested is not the ioname, we
4762 // return 0, as if the member did not exist. In some sense we override
4763 // the information in the TClassInfo instance, isolating the typesystem in
4764 // TClass from the one in the AST.
4765 if (const ValueDecl* decl = (const ValueDecl*) d){
4766 std::string ioName;
4767 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4768 if (hasIoName && ioName != name) return nullptr;
4769 }
4770 return d;
4771 }
4772 // We are looking up for something on the TU scope.
4773 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4774 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4775 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4776 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4777 // are only fulfilling ROOT's understanding for a Data Member.
4778 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4779 // similar as below.
4780 using namespace clang;
4781 Sema& SemaR = fInterpreter->getSema();
4782 DeclarationName DName = &SemaR.Context.Idents.get(name);
4783
4784 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4785 Sema::ForExternalRedeclaration);
4786
4787 cling::utils::Lookup::Named(&SemaR, R);
4788
4789 LookupResult::Filter F = R.makeFilter();
4790 // Filter the data-member looking decls.
4791 while (F.hasNext()) {
4792 NamedDecl *D = F.next();
4793 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4794 isa<IndirectFieldDecl>(D))
4795 continue;
4796 F.erase();
4797 }
4798 F.done();
4799
4800 if (R.isSingleResult())
4801 return R.getFoundDecl();
4802 return nullptr;
4803}
4804
4805////////////////////////////////////////////////////////////////////////////////
4806/// Return pointer to cling Decl of global/static variable that is located
4807/// at the address given by addr.
4808
4810{
4812
4813 const clang::Decl* possibleEnum = nullptr;
4814 // FInd the context of the decl.
4815 if (cl) {
4817 if (cci) {
4818 const clang::DeclContext* dc = nullptr;
4819 if (const clang::Decl* D = cci->GetDecl()) {
4820 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4821 dc = dyn_cast<clang::RecordDecl>(D);
4822 }
4823 }
4824 if (dc) {
4825 // If it is a data member enum.
4826 // Could trigger deserialization of decls.
4827 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4828 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4829 } else {
4830 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4831 }
4832 }
4833 } else {
4834 // If it is a global enum.
4835 // Could trigger deserialization of decls.
4836 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4837 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4838 }
4839 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4840 && isa<clang::EnumDecl>(possibleEnum)) {
4841 return possibleEnum;
4842 }
4843 return nullptr;
4844}
4845
4846////////////////////////////////////////////////////////////////////////////////
4847/// Return pointer to cling DeclId for a global value
4848
4849TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4850{
4851 if (!gv) return nullptr;
4852
4853 llvm::StringRef mangled_name = gv->getName();
4854
4855 int err = 0;
4856 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4857 if (err) {
4858 if (err == -2) {
4859 // It might simply be an unmangled global name.
4860 DeclId_t d;
4862 d = gcl.GetDataMember(mangled_name.str().c_str());
4863 return d;
4864 }
4865 return nullptr;
4866 }
4867
4868 std::string scopename(demangled_name_c);
4869 free(demangled_name_c);
4870
4871 //
4872 // Separate out the class or namespace part of the
4873 // function name.
4874 //
4875 std::string dataname;
4876
4877 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4878 scopename.erase(0, sizeof("typeinfo for ")-1);
4879 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4880 scopename.erase(0, sizeof("vtable for ")-1);
4881 } else {
4882 // See if it is a function
4883 std::string::size_type pos = scopename.rfind('(');
4884 if (pos != std::string::npos) {
4885 return nullptr;
4886 }
4887 // Separate the scope and member name
4888 pos = scopename.rfind(':');
4889 if (pos != std::string::npos) {
4890 if ((pos != 0) && (scopename[pos-1] == ':')) {
4891 dataname = scopename.substr(pos+1);
4892 scopename.erase(pos-1);
4893 }
4894 } else {
4895 scopename.clear();
4896 dataname = scopename;
4897 }
4898 }
4899 //fprintf(stderr, "name: '%s'\n", name.c_str());
4900 // Now we have the class or namespace name, so do the lookup.
4901
4902
4903 DeclId_t d;
4904 if (scopename.size()) {
4905 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4906 d = cl.GetDataMember(dataname.c_str());
4907 }
4908 else {
4910 d = gcl.GetDataMember(dataname.c_str());
4911 }
4912 return d;
4913}
4914
4915////////////////////////////////////////////////////////////////////////////////
4916/// NOT IMPLEMENTED.
4917
4919{
4920 Error("GetDataMemberWithValue()", "not implemented");
4921 return nullptr;
4922}
4923
4924////////////////////////////////////////////////////////////////////////////////
4925/// Return pointer to cling DeclId for a data member with a given name.
4926
4928{
4929 // NOT IMPLEMENTED.
4930 Error("GetDataMemberAtAddr()", "not implemented");
4931 return nullptr;
4932}
4933
4934////////////////////////////////////////////////////////////////////////////////
4935/// Return the cling mangled name for a method of a class with parameters
4936/// params (params is a string of actual arguments, not formal ones). If the
4937/// class is 0 the global function list will be searched.
4938
4939TString TCling::GetMangledName(TClass* cl, const char* method,
4940 const char* params, Bool_t objectIsConst /* = kFALSE */)
4941{
4944 if (cl) {
4946 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4947 &offset);
4948 }
4949 else {
4952 func.SetFunc(&gcl, method, params, &offset);
4953 }
4955 if (!mi) return "";
4956 TString mangled_name( mi->GetMangledName() );
4957 delete mi;
4958 return mangled_name;
4959}
4960
4961////////////////////////////////////////////////////////////////////////////////
4962/// Return the cling mangled name for a method of a class with a certain
4963/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4964/// list will be searched.
4965
4967 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4968 EFunctionMatchMode mode /* = kConversionMatch */)
4969{
4971 if (cl) {
4972 return ((TClingClassInfo*)cl->GetClassInfo())->
4973 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4974 }
4976 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4977}
4978
4979////////////////////////////////////////////////////////////////////////////////
4980/// Return pointer to cling interface function for a method of a class with
4981/// parameters params (params is a string of actual arguments, not formal
4982/// ones). If the class is 0 the global function list will be searched.
4983
4984void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4985 const char* params, Bool_t objectIsConst /* = kFALSE */)
4986{
4989 if (cl) {
4991 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4992 &offset);
4993 }
4994 else {
4997 func.SetFunc(&gcl, method, params, &offset);
4998 }
4999 return (void*) func.InterfaceMethod();
5000}
5001
5002////////////////////////////////////////////////////////////////////////////////
5003/// Return pointer to cling interface function for a method of a class with
5004/// a certain name.
5005
5006TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5007{
5009 DeclId_t f;
5010 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5011 if (cl) {
5012 f = cl->GetMethod(method).GetDeclId();
5013 }
5014 else {
5016 f = gcl.GetMethod(method).GetDeclId();
5017 }
5018 return f;
5019
5020}
5021
5022////////////////////////////////////////////////////////////////////////////////
5023/// Insert overloads of name in cl to res.
5024
5025void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5026 std::vector<DeclId_t>& res) const
5027{
5028 clang::Sema& S = fInterpreter->getSema();
5029 clang::ASTContext& Ctx = S.Context;
5030 const clang::Decl* CtxDecl
5031 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5032 Ctx.getTranslationUnitDecl();
5033 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5034 const clang::DeclContext* DeclCtx = RecDecl;
5035
5036 if (!DeclCtx)
5037 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5038 if (!DeclCtx) return;
5039
5040 clang::DeclarationName DName;
5041 // The DeclarationName is funcname, unless it's a ctor or dtor.
5042 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5043
5044 if (RecDecl) {
5045 if (RecDecl->getNameAsString() == funcname) {
5046 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5047 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5048 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5049 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5050 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5051 } else {
5052 DName = &Ctx.Idents.get(funcname);
5053 }
5054 } else {
5055 DName = &Ctx.Idents.get(funcname);
5056 }
5057
5058 // NotForRedeclaration: we want to find names in inline namespaces etc.
5059 clang::LookupResult R(S, DName, clang::SourceLocation(),
5060 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5061 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5062 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5063 if (R.empty()) return;
5064 R.resolveKind();
5065 res.reserve(res.size() + (R.end() - R.begin()));
5066 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5067 IR != ER; ++IR) {
5068 if (const clang::FunctionDecl* FD
5069 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5070 if (!FD->getDescribedFunctionTemplate()) {
5071 res.push_back(FD);
5072 }
5073 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5074 // FIXME: multi-level using
5075 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5076 res.push_back(USD);
5077 }
5078 }
5079 }
5080}
5081
5082////////////////////////////////////////////////////////////////////////////////
5083/// Return pointer to cling interface function for a method of a class with
5084/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5085/// function list will be searched.
5086
5088 const char* proto,
5089 Bool_t objectIsConst /* = kFALSE */,
5090 EFunctionMatchMode mode /* = kConversionMatch */)
5091{
5093 void* f;
5094 if (cl) {
5095 f = ((TClingClassInfo*)cl->GetClassInfo())->
5096 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5097 }
5098 else {
5100 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5101 }
5102 return f;
5103}
5104
5105////////////////////////////////////////////////////////////////////////////////
5106/// Return pointer to cling DeclId for a method of a class with
5107/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5108/// function list will be searched.
5109
5110TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5111 const char* params,
5112 Bool_t objectIsConst /* = kFALSE */)
5113{
5115 DeclId_t f;
5116 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5117 if (cl) {
5118 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5119 }
5120 else {
5122 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5123 }
5124 return f;
5125}
5126
5127////////////////////////////////////////////////////////////////////////////////
5128/// Return pointer to cling interface function for a method of a class with
5129/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5130/// function list will be searched.
5131
5132TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5133 const char* proto,
5134 Bool_t objectIsConst /* = kFALSE */,
5135 EFunctionMatchMode mode /* = kConversionMatch */)
5136{
5138 DeclId_t f;
5139 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5140 if (cl) {
5141 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5142 }
5143 else {
5145 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5146 }
5147 return f;
5148}
5149
5150////////////////////////////////////////////////////////////////////////////////
5151/// Return pointer to cling interface function for a method of a class with
5152/// a certain name.
5153
5154TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5155{
5157 DeclId_t f;
5158 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5159 if (cl) {
5160 f = cl->GetFunctionTemplate(name);
5161 }
5162 else {
5164 f = gcl.GetFunctionTemplate(name);
5165 }
5166 return f;
5167
5168}
5169
5170////////////////////////////////////////////////////////////////////////////////
5171/// The 'name' is known to the interpreter, this function returns
5172/// the internal version of this name (usually just resolving typedefs)
5173/// This is used in particular to synchronize between the name used
5174/// by rootcling and by the run-time environment (TClass)
5175/// Return 0 if the name is not known.
5176
5177void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5178{
5179 output.clear();
5180
5182
5184 if (!cl.IsValid()) {
5185 return ;
5186 }
5187 if (full) {
5189 return;
5190 }
5191 // Well well well, for backward compatibility we need to act a bit too
5192 // much like CINT.
5195
5196 return;
5197}
5198
5199////////////////////////////////////////////////////////////////////////////////
5200/// Execute a global function with arguments params.
5201///
5202/// FIXME: The cint-based version of this code does not check if the
5203/// SetFunc() call works, and does not do any real checking
5204/// for errors from the Exec() call. It did fetch the most
5205/// recent cint security error and return that in error, but
5206/// this does not really translate well to cling/clang. We
5207/// should enhance these interfaces so that we can report
5208/// compilation and runtime errors properly.
5209
5210void TCling::Execute(const char* function, const char* params, int* error)
5211{
5213 if (error) {
5214 *error = TInterpreter::kNoError;
5215 }
5217 Longptr_t offset = 0L;
5219 func.SetFunc(&cl, function, params, &offset);
5220 func.Exec(nullptr);
5221}
5222
5223////////////////////////////////////////////////////////////////////////////////
5224/// Execute a method from class cl with arguments params.
5225///
5226/// FIXME: The cint-based version of this code does not check if the
5227/// SetFunc() call works, and does not do any real checking
5228/// for errors from the Exec() call. It did fetch the most
5229/// recent cint security error and return that in error, but
5230/// this does not really translate well to cling/clang. We
5231/// should enhance these interfaces so that we can report
5232/// compilation and runtime errors properly.
5233
5234void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5235 const char* params, Bool_t objectIsConst, int* error)
5236{
5238 if (error) {
5239 *error = TInterpreter::kNoError;
5240 }
5241 // If the actual class of this object inherits 2nd (or more) from TObject,
5242 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5243 // hence gInterpreter->Execute will improperly correct the offset.
5244 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5245 Longptr_t offset = 0L;
5247 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5248 void* address = (void*)((Longptr_t)addr + offset);
5249 func.Exec(address);
5250}
5251
5252////////////////////////////////////////////////////////////////////////////////
5253
5254void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5255 const char* params, int* error)
5256{
5257 Execute(obj,cl,method,params,false,error);
5258}
5259
5260////////////////////////////////////////////////////////////////////////////////
5261/// Execute a method from class cl with the arguments in array params
5262/// (params[0] ... params[n] = array of TObjString parameters).
5263/// Convert the TObjArray array of TObjString parameters to a character
5264/// string of comma separated parameters.
5265/// The parameters of type 'char' are enclosed in double quotes and all
5266/// internal quotes are escaped.
5267
5268void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5269 TObjArray* params, int* error)
5270{
5271 if (!method) {
5272 Error("Execute", "No method was defined");
5273 return;
5274 }
5275 TList* argList = method->GetListOfMethodArgs();
5276 // Check number of actual parameters against of expected formal ones
5277
5278 Int_t nparms = argList->LastIndex() + 1;
5279 Int_t argc = params ? params->GetEntries() : 0;
5280
5281 if (argc > nparms) {
5282 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5283 return;
5284 }
5285 if (nparms != argc) {
5286 // Let's see if the 'missing' argument are all defaulted.
5287 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5288 assert(nparms > 0);
5289
5290 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5291 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5292 // There is a default value for the first missing
5293 // argument, so we are fine.
5294 } else {
5295 Int_t firstDefault = -1;
5296 for (Int_t i = 0; i < nparms; i ++) {
5297 arg = (TMethodArg *) argList->At( i );
5298 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5299 firstDefault = i;
5300 break;
5301 }
5302 }
5303 if (firstDefault >= 0) {
5304 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);
5305 } else {
5306 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5307 }
5308 return;
5309 }
5310 }
5311
5312 const char* listpar = "";
5313 TString complete(10);
5314 if (params) {
5315 // Create a character string of parameters from TObjArray
5316 TIter next(params);
5317 for (Int_t i = 0; i < argc; i ++) {
5318 TMethodArg* arg = (TMethodArg*) argList->At(i);
5320 TObjString* nxtpar = (TObjString*) next();
5321 if (i) {
5322 complete += ',';
5323 }
5324 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5325 TString chpar('\"');
5326 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5327 // At this point we have to check if string contains \\"
5328 // and apply some more sophisticated parser. Not implemented yet!
5329 complete += chpar;
5330 complete += '\"';
5331 }
5332 else {
5333 complete += nxtpar->String();
5334 }
5335 }
5336 listpar = complete.Data();
5337 }
5338
5339 // And now execute it.
5341 if (error) {
5342 *error = TInterpreter::kNoError;
5343 }
5344 // If the actual class of this object inherits 2nd (or more) from TObject,
5345 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5346 // hence gInterpreter->Execute will improperly correct the offset.
5347 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5349 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5350 func.Init(*minfo);
5351 func.SetArgs(listpar);
5352 // Now calculate the 'this' pointer offset for the method
5353 // when starting from the class described by cl.
5354 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5355 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5356 void* address = (void*)((Longptr_t)addr + offset);
5357 func.Exec(address);
5358}
5359
5360////////////////////////////////////////////////////////////////////////////////
5361
5362void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5363 const void* args[] /*=0*/,
5364 int nargs /*=0*/,
5365 void* ret/*= 0*/) const
5366{
5367 if (!method) {
5368 Error("ExecuteWithArgsAndReturn", "No method was defined");
5369 return;
5370 }
5371
5372 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5373 TClingCallFunc func(*minfo);
5374 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5375}
5376
5377////////////////////////////////////////////////////////////////////////////////
5378/// Execute a cling macro.
5379
5381{
5383 fCurExecutingMacros.push_back(filename);
5385 fCurExecutingMacros.pop_back();
5386 return result;
5387}
5388
5389////////////////////////////////////////////////////////////////////////////////
5390/// Return the file name of the current un-included interpreted file.
5391/// See the documentation for GetCurrentMacroName().
5392
5394{
5395 Warning("GetTopLevelMacroName", "Must change return type!");
5396 return fCurExecutingMacros.back();
5397}
5398
5399////////////////////////////////////////////////////////////////////////////////
5400/// Return the file name of the currently interpreted file,
5401/// included or not. Example to illustrate the difference between
5402/// GetCurrentMacroName() and GetTopLevelMacroName():
5403/// ~~~ {.cpp}
5404/// void inclfile() {
5405/// std::cout << "In inclfile.C" << std::endl;
5406/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5407/// TCling::GetCurrentMacroName() << std::endl;
5408/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5409/// TCling::GetTopLevelMacroName() << std::endl;
5410/// }
5411/// ~~~
5412/// ~~~ {.cpp}
5413/// void mymacro() {
5414/// std::cout << "In mymacro.C" << std::endl;
5415/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5416/// TCling::GetCurrentMacroName() << std::endl;
5417/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5418/// TCling::GetTopLevelMacroName() << std::endl;
5419/// std::cout << " Now calling inclfile..." << std::endl;
5420/// gInterpreter->ProcessLine(".x inclfile.C");;
5421/// }
5422/// ~~~
5423/// Running mymacro.C will print:
5424///
5425/// ~~~ {.cpp}
5426/// root [0] .x mymacro.C
5427/// ~~~
5428/// In mymacro.C
5429/// ~~~ {.cpp}
5430/// TCling::GetCurrentMacroName() returns ./mymacro.C
5431/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5432/// ~~~
5433/// Now calling inclfile...
5434/// In inclfile.h
5435/// ~~~ {.cpp}
5436/// TCling::GetCurrentMacroName() returns inclfile.C
5437/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5438/// ~~~
5439
5441{
5442#if defined(R__MUST_REVISIT)
5443#if R__MUST_REVISIT(6,0)
5444 Warning("GetCurrentMacroName", "Must change return type!");
5445#endif
5446#endif
5447 return fCurExecutingMacros.back();
5448}
5449
5450////////////////////////////////////////////////////////////////////////////////
5451/// Return the absolute type of typeDesc.
5452/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5453/// You need to use the result immediately before it is being overwritten.
5454
5455const char* TCling::TypeName(const char* typeDesc)
5456{
5457 TTHREAD_TLS_DECL(std::string,t);
5458
5459 if (!strstr(typeDesc, "(*)(")) {
5460 const char *s = strchr(typeDesc, ' ');
5461 const char *template_start = strchr(typeDesc, '<');
5462 if (!strcmp(typeDesc, "long long")) {
5463 t = typeDesc;
5464 }
5465 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5466 t = typeDesc;
5467 }
5468 // s is the position of the second 'word' (if any)
5469 // except in the case of templates where there will be a space
5470 // just before any closing '>': eg.
5471 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5472 else if (s && (template_start == nullptr || (s < template_start))) {
5473 t = s + 1;
5474 }
5475 else {
5476 t = typeDesc;
5477 }
5478 }
5479 else {
5480 t = typeDesc;
5481 }
5482 auto l = t.length();
5483 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5484 --l;
5485 t.resize(l);
5486 return t.c_str(); // NOLINT
5487}
5488
5489static bool requiresRootMap(const char* rootmapfile)
5490{
5491 assert(rootmapfile && *rootmapfile);
5492
5493 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5494 libName.consume_back(".rootmap");
5495
5496 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5497}
5498
5499////////////////////////////////////////////////////////////////////////////////
5500/// Read and parse a rootmapfile in its new format, and return 0 in case of
5501/// success, -1 if the file has already been read, and -3 in case its format
5502/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5503/// error.
5504
5505int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5506{
5507 if (!(rootmapfile && *rootmapfile))
5508 return 0;
5509
5510 if (!requiresRootMap(rootmapfile))
5511 return 0; // success
5512
5513 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5514 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5515
5516 std::string rootmapfileNoBackslash(rootmapfile);
5517#ifdef _MSC_VER
5518 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5519#endif
5520 // Add content of a specific rootmap file
5521 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5522 return -1;
5523
5524 // Line 1 is `{ decls }`
5525 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5526
5527 std::ifstream file(rootmapfileNoBackslash);
5528 std::string line;
5529 line.reserve(200);
5530 std::string lib_name;
5531 line.reserve(100);
5532 bool newFormat = false;
5533 while (getline(file, line, '\n')) {
5534 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5535 file.close();
5536 return -3; // old format
5537 }
5538 newFormat = true;
5539
5540 if (line.compare(0, 9, "{ decls }") == 0) {
5541 // forward declarations
5542
5543 while (getline(file, line, '\n')) {
5544 if (line[0] == '[')
5545 break;
5546 if (!uniqueString) {
5547 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5548 rootmapfileNoBackslash.c_str());
5549 return -4;
5550 }
5551 if (!lineDirective.empty())
5552 uniqueString->Append(lineDirective);
5553 uniqueString->Append(line + '\n');
5554 }
5555 }
5556 const char firstChar = line[0];
5557 if (firstChar == '[') {
5558 // new section (library)
5559 auto brpos = line.find(']');
5560 if (brpos == string::npos)
5561 continue;
5562 lib_name = line.substr(1, brpos - 1);
5563 // Remove spaces at the beginning and at the end of the library name
5564 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5565 lib_name.erase(0, lib_name.find_first_not_of(' '));
5566 if (gDebug > 3) {
5567 TString lib_nameTstr(lib_name.c_str());
5568 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5569 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5570 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5571 if (wlib) {
5572 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5573 } else {
5574 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5575 }
5576 delete[] wlib;
5577 delete tokens;
5578 }
5579 } else {
5580 auto keyLenIt = keyLenMap.find(firstChar);
5581 if (keyLenIt == keyLenMap.end())
5582 continue;
5583 unsigned int keyLen = keyLenIt->second;
5584 // Do not make a copy, just start after the key
5585 const char *keyname = line.c_str() + keyLen;
5586 if (gDebug > 6)
5587 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5588 TEnvRec *isThere = fMapfile->Lookup(keyname);
5589 if (isThere) {
5590 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5591 if (firstChar == 'n') {
5592 if (gDebug > 3)
5593 Info("ReadRootmapFile",
5594 "While processing %s, namespace %s was found to be associated to %s although it is already "
5595 "associated to %s",
5596 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5597 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5598 lib_name += " ";
5599 lib_name += isThere->GetValue();
5600 fMapfile->SetValue(keyname, lib_name.c_str());
5601 } else if (!TClassEdit::IsSTLCont(keyname)) {
5602 Warning("ReadRootmapFile",
5603 "While processing %s, %s %s was found to be associated to %s although it is already "
5604 "associated to %s",
5605 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5606 isThere->GetValue());
5607 }
5608 } else { // the same key for the same lib
5609 if (gDebug > 3)
5610 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5611 rootmapfile, keyname, lib_name.c_str());
5612 }
5613 } else {
5614 fMapfile->SetValue(keyname, lib_name.c_str());
5615 }
5616 }
5617 }
5618 file.close();
5619 return 0;
5620}
5621
5622////////////////////////////////////////////////////////////////////////////////
5623/// Create a resource table and read the (possibly) three resource files,
5624/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5625/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5626/// can read additional user defined resource files by creating additional TEnv
5627/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5628/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5629/// case the home directory resides on an automounted remote file system
5630/// and one wants to avoid the file system from being mounted.
5631
5633{
5634 assert(requiresRootMap(name) && "We have a module!");
5635
5636 if (!requiresRootMap(name))
5637 return;
5638
5640
5642
5643 TString sname = "system";
5644 sname += name;
5645 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5646
5647 Int_t ret = ReadRootmapFile(s);
5648 if (ret == -3) // old format
5650 delete [] s;
5651 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5653 ret = ReadRootmapFile(s);
5654 if (ret == -3) // old format
5656 delete [] s;
5657 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5658 ret = ReadRootmapFile(name);
5659 if (ret == -3) // old format
5661 }
5662 } else {
5663 ret = ReadRootmapFile(name);
5664 if (ret == -3) // old format
5666 }
5667 fMapfile->IgnoreDuplicates(ignore);
5668}
5669
5670
5671namespace {
5672 using namespace clang;
5673
5674 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5675 // This class is to be considered an helper for AutoLoading.
5676 // It is a recursive visitor is used to inspect namespaces and specializations
5677 // coming from forward declarations in rootmaps and to set the external visible
5678 // storage flag for them.
5679 public:
5680 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5681 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5682 // We want to enable the external lookup for this namespace
5683 // because it may shadow the lookup of other names contained
5684 // in that namespace
5685
5686 nsDecl->setHasExternalVisibleStorage();
5687 fNSSet.insert(nsDecl);
5688 return true;
5689 }
5690 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5691 // We want to enable the external lookup for this specialization
5692 // because we can provide a definition for it!
5693 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5694 //SpecSet.insert(specDecl);
5695 specDecl->setHasExternalLexicalStorage();
5696
5697 // No need to recurse. On the contrary, recursing is actively harmful:
5698 // NOTE: must not recurse to prevent this visitor from triggering loading from
5699 // the external AST source (i.e. autoloading). This would be triggered right here,
5700 // before autoloading is even set up, as rootmap file parsing happens before that.
5701 // Even if autoloading is off and has no effect, triggering loading from external
5702 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5703 // from subsequent autoloads!
5704 return false;
5705 }
5706 private:
5707 std::unordered_set<const NamespaceDecl*>& fNSSet;
5708 };
5709}
5710
5711////////////////////////////////////////////////////////////////////////////////
5712/// Load map between class and library. If rootmapfile is specified a
5713/// specific rootmap file can be added (typically used by ACLiC).
5714/// In case of error -1 is returned, 0 otherwise.
5715/// The interpreter uses this information to automatically load the shared
5716/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5717
5718Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5719{
5720 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5721 return 0;
5722
5724
5725 // open the [system].rootmap files
5726 if (!fMapfile) {
5727 fMapfile = new TEnv();
5731 InitRootmapFile(".rootmap");
5732 }
5733
5734 // Prepare a list of all forward declarations for cling
5735 // For some experiments it is easily as big as 500k characters. To be on the
5736 // safe side, we go for 1M.
5737 TUniqueString uniqueString(1048576);
5738
5739 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5740 // A rootmap file must end with the string ".rootmap".
5741 TString ldpath = gSystem->GetDynamicPath();
5742 if (ldpath != fRootmapLoadPath) {
5743 fRootmapLoadPath = ldpath;
5744#ifdef WIN32
5745 TObjArray* paths = ldpath.Tokenize(";");
5746#else
5747 TObjArray* paths = ldpath.Tokenize(":");
5748#endif
5749 TString d;
5750 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5751 d = ((TObjString *)paths->At(i))->GetString();
5752 // check if directory already scanned
5753 Int_t skip = 0;
5754 for (Int_t j = 0; j < i; j++) {
5755 TString pd = ((TObjString *)paths->At(j))->GetString();
5756 if (pd == d) {
5757 skip++;
5758 break;
5759 }
5760 }
5761 if (!skip) {
5762 void* dirp = gSystem->OpenDirectory(d);
5763 if (dirp) {
5764 if (gDebug > 3) {
5765 Info("LoadLibraryMap", "%s", d.Data());
5766 }
5767 const char* f1;
5768 while ((f1 = gSystem->GetDirEntry(dirp))) {
5769 TString f = f1;
5770 if (f.EndsWith(".rootmap")) {
5771 TString p;
5772 p = d + "/" + f;
5774 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5775 if (gDebug > 4) {
5776 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5777 }
5778 Int_t ret = ReadRootmapFile(p, &uniqueString);
5779
5780 if (ret == 0)
5781 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5782 if (ret == -3) {
5783 // old format
5785 fRootmapFiles->Add(new TNamed(f, p));
5786 }
5787 }
5788 // else {
5789 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5790 // fRootmapFiles->FindObject(f)->ls();
5791 // }
5792 }
5793 }
5794 if (f.BeginsWith("rootmap")) {
5795 TString p;
5796 p = d + "/" + f;
5797 FileStat_t stat;
5798 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5799 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5800 }
5801 }
5802 }
5803 }
5804 gSystem->FreeDirectory(dirp);
5805 }
5806 }
5807 delete paths;
5808 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5809 return -1;
5810 }
5811 }
5812 if (rootmapfile && *rootmapfile) {
5813 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5814 if (res == 0) {
5815 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5816 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5817 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5818 }
5819 else if (res == -3) {
5820 // old format
5822 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5823 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5824 fMapfile->IgnoreDuplicates(ignore);
5825 }
5826 }
5827 TEnvRec* rec;
5828 TIter next(fMapfile->GetTable());
5829 while ((rec = (TEnvRec*) next())) {
5830 TString cls = rec->GetName();
5831 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5832 // get the first lib from the list of lib and dependent libs
5833 TString libs = rec->GetValue();
5834 if (libs == "") {
5835 continue;
5836 }
5837 TString delim(" ");
5838 TObjArray* tokens = libs.Tokenize(delim);
5839 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5840 // convert "@@" to "::", we used "@@" because TEnv
5841 // considers "::" a terminator
5842 cls.Remove(0, 8);
5843 cls.ReplaceAll("@@", "::");
5844 // convert "-" to " ", since class names may have
5845 // blanks and TEnv considers a blank a terminator
5846 cls.ReplaceAll("-", " ");
5847 if (gDebug > 6) {
5848 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5849 if (wlib) {
5850 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5851 }
5852 else {
5853 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5854 }
5855 delete[] wlib;
5856 }
5857 delete tokens;
5858 }
5859 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5860 cls.Remove(0, 8);
5861 // convert "-" to " ", since class names may have
5862 // blanks and TEnv considers a blank a terminator
5863 cls.ReplaceAll("-", " ");
5864 fInterpreter->declare(cls.Data());
5865 }
5866 }
5867
5868 // Process the forward declarations collected
5869 cling::Transaction* T = nullptr;
5870 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5871 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5872
5873 if (compRes!=cling::Interpreter::kSuccess){
5874 Warning("LoadLibraryMap",
5875 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5876 }
5877
5878 if (T) {
5879 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5880 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5881 if (declIt->m_DGR.isSingleDecl()) {
5882 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5883 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5884 evsAdder.TraverseDecl(D);
5885 }
5886 }
5887 }
5888 }
5889 }
5890
5891 // clear duplicates
5892
5893 return 0;
5894}
5895
5896////////////////////////////////////////////////////////////////////////////////
5897/// Scan again along the dynamic path for library maps. Entries for the loaded
5898/// shared libraries are unloaded first. This can be useful after reseting
5899/// the dynamic path through TSystem::SetDynamicPath()
5900/// In case of error -1 is returned, 0 otherwise.
5901
5903{
5906 return 0;
5907}
5908
5909////////////////////////////////////////////////////////////////////////////////
5910/// Reload the library map entries coming from all the loaded shared libraries,
5911/// after first unloading the current ones.
5912/// In case of error -1 is returned, 0 otherwise.
5913
5915{
5916 const TString sharedLibLStr = GetSharedLibs();
5917 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5918 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5919 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5920 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5921 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5922 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5923 if (ret < 0) {
5924 continue;
5925 }
5926 TString rootMapBaseStr = sharedLibBaseStr;
5927 if (sharedLibBaseStr.EndsWith(".dll")) {
5928 rootMapBaseStr.ReplaceAll(".dll", "");
5929 }
5930 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5931 rootMapBaseStr.ReplaceAll(".DLL", "");
5932 }
5933 else if (sharedLibBaseStr.EndsWith(".so")) {
5934 rootMapBaseStr.ReplaceAll(".so", "");
5935 }
5936 else if (sharedLibBaseStr.EndsWith(".sl")) {
5937 rootMapBaseStr.ReplaceAll(".sl", "");
5938 }
5939 else if (sharedLibBaseStr.EndsWith(".dl")) {
5940 rootMapBaseStr.ReplaceAll(".dl", "");
5941 }
5942 else if (sharedLibBaseStr.EndsWith(".a")) {
5943 rootMapBaseStr.ReplaceAll(".a", "");
5944 }
5945 else {
5946 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5947 delete sharedLibL;
5948 return -1;
5949 }
5950 rootMapBaseStr += ".rootmap";
5951 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5952 if (!rootMap) {
5953 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5954 delete[] rootMap;
5955 delete sharedLibL;
5956 return -1;
5957 }
5958 const Int_t status = LoadLibraryMap(rootMap);
5959 if (status < 0) {
5960 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5961 delete[] rootMap;
5962 delete sharedLibL;
5963 return -1;
5964 }
5965 delete[] rootMap;
5966 }
5967 delete sharedLibL;
5968 return 0;
5969}
5970
5971////////////////////////////////////////////////////////////////////////////////
5972/// Unload the library map entries coming from all the loaded shared libraries.
5973/// Returns 0 if succesful
5974
5976{
5977 const TString sharedLibLStr = GetSharedLibs();
5978 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5979 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5980 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5981 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5982 UnloadLibraryMap(sharedLibBaseStr);
5983 }
5984 delete sharedLibL;
5985 return 0;
5986}
5987
5988////////////////////////////////////////////////////////////////////////////////
5989/// Unload library map entries coming from the specified library.
5990/// Returns -1 in case no entries for the specified library were found,
5991/// 0 otherwise.
5992
5994{
5995 if (!fMapfile || !library || !*library) {
5996 return 0;
5997 }
5998 TString libname(library);
5999 Ssiz_t idx = libname.Last('.');
6000 if (idx != kNPOS) {
6001 libname.Remove(idx);
6002 }
6003 size_t len = libname.Length();
6004 TEnvRec *rec;
6005 TIter next(fMapfile->GetTable());
6007 Int_t ret = 0;
6008 while ((rec = (TEnvRec *) next())) {
6009 TString cls = rec->GetName();
6010 if (cls.Length() > 2) {
6011 // get the first lib from the list of lib and dependent libs
6012 TString libs = rec->GetValue();
6013 if (libs == "") {
6014 continue;
6015 }
6016 TString delim(" ");
6017 TObjArray* tokens = libs.Tokenize(delim);
6018 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6019 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6020 // convert "@@" to "::", we used "@@" because TEnv
6021 // considers "::" a terminator
6022 cls.Remove(0, 8);
6023 cls.ReplaceAll("@@", "::");
6024 // convert "-" to " ", since class names may have
6025 // blanks and TEnv considers a blank a terminator
6026 cls.ReplaceAll("-", " ");
6027 }
6028 if (!strncmp(lib, libname.Data(), len)) {
6029 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6030 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6031 ret = -1;
6032 }
6033 }
6034 delete tokens;
6035 }
6036 }
6037 if (ret >= 0) {
6038 TString library_rootmap(library);
6039 if (!library_rootmap.EndsWith(".rootmap"))
6040 library_rootmap.Append(".rootmap");
6041 TNamed* mfile = nullptr;
6042 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6043 fRootmapFiles->Remove(mfile);
6044 delete mfile;
6045 }
6047 }
6048 return ret;
6049}
6050
6051////////////////////////////////////////////////////////////////////////////////
6052/// Register the AutoLoading information for a class.
6053/// libs is a space separated list of libraries.
6054
6055Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6056{
6057 if (!cls || !*cls)
6058 return 0;
6059
6060 TString key = TString("Library.") + cls;
6061 // convert "::" to "@@", we used "@@" because TEnv
6062 // considers "::" a terminator
6063 key.ReplaceAll("::", "@@");
6064 // convert "-" to " ", since class names may have
6065 // blanks and TEnv considers a blank a terminator
6066 key.ReplaceAll(" ", "-");
6067
6069 if (!fMapfile) {
6070 fMapfile = new TEnv();
6072
6075
6076 InitRootmapFile(".rootmap");
6077 }
6078 //fMapfile->SetValue(key, libs);
6079 fMapfile->SetValue(cls, libs);
6080 return 1;
6081}
6082
6083////////////////////////////////////////////////////////////////////////////////
6084/// Demangle the name (from the typeinfo) and then request the class
6085/// via the usual name based interface (TClass::GetClass).
6086
6087TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6088{
6089 int err = 0;
6090 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6091 if (err) return nullptr;
6092 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6093 free(demangled_name);
6094 return theClass;
6095}
6096
6097////////////////////////////////////////////////////////////////////////////////
6098/// Load library containing the specified class. Returns 0 in case of error
6099/// and 1 in case if success.
6100
6101Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6102{
6103 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6104
6105 int err = 0;
6106 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6107 if (err) {
6108 return 0;
6109 }
6110
6111 std::string demangled_name(demangled_name_c);
6112 free(demangled_name_c);
6113
6114 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6115 // shortened name.
6117 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6118
6119 // No need to worry about typedef, they aren't any ... but there are
6120 // inlined namespaces ...
6121
6122 Int_t result = AutoLoad(demangled_name.c_str());
6123 if (result == 0) {
6124 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6125 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6126 }
6127
6128 return result;
6129}
6130
6131////////////////////////////////////////////////////////////////////////////////
6132// Get the list of 'published'/'known' library for the class and load them.
6134{
6135 Int_t status = 0;
6136
6137 // lookup class to find list of dependent libraries
6138 TString deplibs = gCling->GetClassSharedLibs(cls);
6139 if (!deplibs.IsNull()) {
6140 TString delim(" ");
6141 TObjArray* tokens = deplibs.Tokenize(delim);
6142 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6143 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6144 if (gROOT->LoadClass(cls, deplib) == 0) {
6145 if (gDebug > 0) {
6146 gCling->Info("TCling::AutoLoad",
6147 "loaded dependent library %s for %s", deplib, cls);
6148 }
6149 }
6150 else {
6151 gCling->Error("TCling::AutoLoad",
6152 "failure loading dependent library %s for %s",
6153 deplib, cls);
6154 }
6155 }
6156 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6157 if (lib && lib[0]) {
6158 if (gROOT->LoadClass(cls, lib) == 0) {
6159 if (gDebug > 0) {
6160 gCling->Info("TCling::AutoLoad",
6161 "loaded library %s for %s", lib, cls);
6162 }
6163 status = 1;
6164 }
6165 else {
6166 gCling->Error("TCling::AutoLoad",
6167 "failure loading library %s for %s", lib, cls);
6168 }
6169 }
6170 delete tokens;
6171 }
6172
6173 return status;
6174}
6175
6176////////////////////////////////////////////////////////////////////////////////
6177// Iterate through the data member of the class (either through the TProtoClass
6178// or through Cling) and trigger, recursively, the loading the necessary libraries.
6179// \note `cls` is expected to be already normalized!
6180// \returns 1 on success.
6181Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6182 bool nameIsNormalized)
6183{
6184 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6185 // has previously (within the same call to `AutoLoad()`) tried to load this class
6186 // and we are done, whether success or not, as it won't work better now than before,
6187 // because there is no additional information now compared to before.
6188 if (!visited.insert(std::string(cls)).second)
6189 return 1;
6190
6191 if (ShallowAutoLoadImpl(cls) == 0) {
6192 // If ShallowAutoLoadImpl() has an error, we have an error.
6193 return 0;
6194 }
6195
6196 // Now look through the TProtoClass to load the required library/dictionary
6197 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6198 for (auto element : proto->GetData()) {
6199 if (element->IsBasic())
6200 continue;
6201 const char *subtypename = element->GetTypeName();
6202 if (!TClassTable::GetDictNorm(subtypename)) {
6203 // Failure to load a dictionary is not (quite) a failure load
6204 // the top-level library. If we return false here, then
6205 // we would end up in a situation where the library and thus
6206 // the dictionary is loaded for "cls" but the TClass is
6207 // not created and/or marked as unavailable (in case where
6208 // AutoLoad is called from TClass::GetClass).
6209 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6210 }
6211 }
6212 return 1;
6213 }
6214
6215 // We found no TProtoClass for cls.
6216 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6217 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6218 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6219 {
6220 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6221 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6222 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6223 continue;
6224 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6225 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6226 // Failure to load a dictionary is not (quite) a failure load
6227 // the top-level library. See detailed comment in the TProtoClass
6228 // branch (above).
6229 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6230 }
6231 }
6232 gInterpreter->DataMemberInfo_Delete(memberinfo);
6233 }
6234 gInterpreter->ClassInfo_Delete(classinfo);
6235 return 1;
6236}
6237
6238////////////////////////////////////////////////////////////////////////////////
6239/// Load library containing the specified class. Returns 0 in case of error
6240/// and 1 in case if success.
6241
6242Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6243{
6244 // Prevent update to IsClassAutoloading between our check and our actions.
6246
6247 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6248 // rootcling (in *_rdict.pcm file generation) it is a no op.
6249 // FIXME: We should avoid calling autoload when we know we are not supposed
6250 // to and transform this check into an assert.
6252 // Never load any library from rootcling/genreflex.
6253 if (gDebug > 2) {
6254 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6255 }
6256 return 0;
6257 }
6258
6259 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6260
6262
6263 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6264 // The library is already loaded as the class's dictionary is known.
6265 // Return success.
6266 // Note: the name (cls) is expected to be normalized as it comes either
6267 // from a callbacks (that can/should calculate the normalized name from the
6268 // decl) or from TClass::GetClass (which does also calculate the normalized
6269 // name).
6270 return 1;
6271 }
6272
6273 if (gDebug > 2) {
6274 Info("TCling::AutoLoad",
6275 "Trying to autoload for %s", cls);
6276 }
6277
6278 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6279 if (gDebug > 2) {
6280 Info("TCling::AutoLoad",
6281 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6282 }
6283 return 0;
6284 }
6285 // Prevent the recursion when the library dictionary are loaded.
6286 SuspendAutoLoadingRAII autoLoadOff(this);
6287 // Try using externally provided callback first.
6288 if (fAutoLoadCallBack) {
6289 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6290 if (success)
6291 return success;
6292 }
6293
6294 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6295 // (when module are enabled) which might end up calling AutoParsing but
6296 // that should only be for the cases where the library has no generated pcm
6297 // and in that case a rootmap should be available.
6298 // This avoids a very costly operation (for generally no gain) but reduce the
6299 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6300 // file).
6301 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6302 std::unordered_set<std::string> visited;
6303 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6304}
6305
6306////////////////////////////////////////////////////////////////////////////////
6307/// Parse the payload or header.
6308
6309static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6310 Bool_t header,
6311 cling::Interpreter *interpreter)
6312{
6313 std::string code = gNonInterpreterClassDef ;
6314 if (!header) {
6315 // This is the complete header file content and not the
6316 // name of a header.
6317 code += what;
6318
6319 } else {
6320 code += ("#include \"");
6321 code += what;
6322 code += "\"\n";
6323 }
6324 code += ("#ifdef __ROOTCLING__\n"
6325 "#undef __ROOTCLING__\n"
6326 + gInterpreterClassDef +
6327 "#endif");
6328
6329 cling::Interpreter::CompilationResult cr;
6330 {
6331 // scope within which diagnostics are de-activated
6332 // For now we disable diagnostics because we saw them already at
6333 // dictionary generation time. That won't be an issue with the PCMs.
6334
6335 Sema &SemaR = interpreter->getSema();
6336 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6337 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6338
6339 #if defined(R__MUST_REVISIT)
6340 #if R__MUST_REVISIT(6,2)
6341 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6342 #endif
6343 #endif
6344
6345 cr = interpreter->parseForModule(code);
6346 }
6347 return cr;
6348}
6349
6350////////////////////////////////////////////////////////////////////////////////
6351/// Helper routine for TCling::AutoParse implementing the actual call to the
6352/// parser and looping over template parameters (if
6353/// any) and when they don't have a registered header to autoparse,
6354/// recurse over their template parameters.
6355///
6356/// Returns the number of header parsed.
6357
6358UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6359{
6360 // We assume the lock has already been taken.
6361 // R__LOCKGUARD(gInterpreterMutex);
6362
6363 Int_t nHheadersParsed = 0;
6364 unsigned long offset = 0;
6365 if (strncmp(cls, "const ", 6) == 0) {
6366 offset = 6;
6367 }
6368
6369 // Loop on the possible autoparse keys
6370 bool skipFirstEntry = false;
6371 std::vector<std::string> autoparseKeys;
6372 if (strchr(cls, '<')) {
6373 int nestedLoc = 0;
6374 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6375 // Check if we can skip the name of the template in the autoparses
6376 // Take all the scopes one by one. If all of them are in the AST, we do not
6377 // need to autoparse for that particular template.
6378 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6379 // autoparseKeys[0] is empty when the input is not a template instance.
6380 // The case strchr(cls, '<') != 0 but still not a template instance can
6381 // happens 'just' for string (GetSplit replaces the template by the short name
6382 // and then use that for thew splitting)
6383 TString templateName(autoparseKeys[0]);
6384 auto tokens = templateName.Tokenize("::");
6385 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6386 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6387 if (TClassEdit::IsStdClass(cls + offset))
6388 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6389 auto nTokens = tokens->GetEntriesFast();
6390 for (Int_t tk = 0; tk < nTokens; ++tk) {
6391 auto scopeObj = tokens->UncheckedAt(tk);
6392 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6393 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6394 // Check if we have multiple nodes in the AST with this name
6395 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6396 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6397 if (!previousScopeAsContext) break; // this is not a context
6398 }
6399 delete tokens;
6400 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6401 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6402 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6403 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6404 skipFirstEntry = templatedDecl->hasDefinition();
6405 }
6406 }
6407 }
6408
6409 }
6410 }
6411 if (topLevel) autoparseKeys.emplace_back(cls);
6412
6413 for (const auto & apKeyStr : autoparseKeys) {
6414 if (skipFirstEntry) {
6415 skipFirstEntry=false;
6416 continue;
6417 }
6418 if (apKeyStr.empty()) continue;
6419 const char *apKey = apKeyStr.c_str();
6420 std::size_t normNameHash(fStringHashFunction(apKey));
6421 // If the class was not looked up
6422 if (gDebug > 1) {
6423 Info("TCling::AutoParse",
6424 "Starting autoparse for %s\n", apKey);
6425 }
6426 if (fLookedUpClasses.insert(normNameHash).second) {
6427 auto const &iter = fClassesHeadersMap.find(normNameHash);
6428 if (iter != fClassesHeadersMap.end()) {
6429 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6430 fTransactionHeadersMap.insert({T,normNameHash});
6431 auto const &hNamesPtrs = iter->second;
6432 if (gDebug > 1) {
6433 Info("TCling::AutoParse",
6434 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6435 }
6436 for (auto & hName : hNamesPtrs) {
6437 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6438 if (0 != fPayloads.count(normNameHash)) {
6439 float initRSSval=0.f, initVSIZEval=0.f;
6440 (void) initRSSval; // Avoid unused var warning
6441 (void) initVSIZEval;
6442 if (gDebug > 0) {
6443 Info("AutoParse",
6444 "Parsing full payload for %s", apKey);
6445 ProcInfo_t info;
6446 gSystem->GetProcInfo(&info);
6447 initRSSval = 1e-3*info.fMemResident;
6448 initVSIZEval = 1e-3*info.fMemVirtual;
6449 }
6450 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6451 if (cRes != cling::Interpreter::kSuccess) {
6452 if (hName[0] == '\n')
6453 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6454 } else {
6455 fParsedPayloadsAddresses.insert(hName);
6456 nHheadersParsed++;
6457 if (gDebug > 0){
6458 ProcInfo_t info;
6459 gSystem->GetProcInfo(&info);
6460 float endRSSval = 1e-3*info.fMemResident;
6461 float endVSIZEval = 1e-3*info.fMemVirtual;
6462 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6463 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6464 }
6465 }
6466 } else if (!IsLoaded(hName)) {
6467 if (gDebug > 0) {
6468 Info("AutoParse",
6469 "Parsing single header %s", hName);
6470 }
6471 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6472 if (cRes != cling::Interpreter::kSuccess) {
6473 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6474 } else {
6475 nHheadersParsed++;
6476 }
6477 }
6478 }
6479 }
6480 else {
6481 // There is no header registered for this class, if this a
6482 // template, it will be instantiated if/when it is requested
6483 // and if we do no load/parse its components we might end up
6484 // not using an eventual specialization.
6485 if (strchr(apKey, '<')) {
6486 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6487 }
6488 }
6489 }
6490 }
6491
6492 return nHheadersParsed;
6493
6494}
6495
6496////////////////////////////////////////////////////////////////////////////////
6497/// Parse the headers relative to the class
6498/// Returns 1 in case of success, 0 in case of failure
6499
6500Int_t TCling::AutoParse(const char *cls)
6501{
6502 if (llvm::StringRef(cls).contains("(lambda)"))
6503 return 0;
6504
6507 return AutoLoad(cls);
6508 } else {
6509 return 0;
6510 }
6511 }
6512
6514
6515 if (gDebug > 1) {
6516 Info("TCling::AutoParse",
6517 "Trying to autoparse for %s", cls);
6518 }
6519
6520 // The catalogue of headers is in the dictionary
6522 && !gClassTable->GetDictNorm(cls)) {
6523 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6524 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6525 fInterpreter->getSema());
6526 AutoLoad(cls, true /*knowDictNotLoaded*/);
6527 }
6528
6529 // Prevent the recursion when the library dictionary are loaded.
6530 SuspendAutoLoadingRAII autoLoadOff(this);
6531
6532 // No recursive header parsing on demand; we require headers to be standalone.
6533 SuspendAutoParsing autoParseRAII(this);
6534
6535 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6536
6538
6539 return nHheadersParsed > 0 ? 1 : 0;
6540}
6541
6542// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6543// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6544// false if not.
6545bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6546{
6547 StringRef errMsg(errmessage);
6548 if (errMsg.contains("undefined symbol: ")) {
6549 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6550 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6551 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6552 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6553 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6554 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6555 return true;
6556 } else {
6557 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6558 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6559 return true;
6560 }
6561
6562 return false;
6563}
6564
6565////////////////////////////////////////////////////////////////////////////////
6566/// Autoload a library based on a missing symbol.
6567
6568void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6569 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6570
6571 // We have already loaded the library.
6572 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6573 return Addr;
6574
6575 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6577
6578 auto LibLoader = [](const std::string& LibName) -> bool {
6579 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6580 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6581 "Failed to load library %s", LibName.c_str());
6582 return false;
6583 }
6584 return true; //success.
6585 };
6586
6587 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6588 /*searchSystem=*/ true);
6589
6590 assert(!llvm::StringRef(libName).startswith("libNew") &&
6591 "We must not resolve symbols from libNew!");
6592
6593 if (libName.empty())
6594 return nullptr;
6595
6596 if (!LibLoader(libName))
6597 return nullptr;
6598
6599 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6600}
6601
6602////////////////////////////////////////////////////////////////////////////////
6603
6604Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6605{
6606 return fNSFromRootmaps.count(nsDecl) != 0;
6607}
6608
6609////////////////////////////////////////////////////////////////////////////////
6610/// Internal function. Actually do the update of the ClassInfo when seeing
6611// new TagDecl or NamespaceDecl.
6612void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6613{
6614
6616 if (cci) {
6617 // If we only had a forward declaration then update the
6618 // TClingClassInfo with the definition if we have it now.
6619 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6620 if (!oldDef || (def && def != oldDef)) {
6621 cl->ResetCaches();
6623 if (def) {
6624 // It's a tag decl, not a namespace decl.
6625 cci->Init(*cci->GetType());
6627 }
6628 }
6629 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6630 cl->ResetCaches();
6631 // yes, this is almost a waste of time, but we do need to lookup
6632 // the 'type' corresponding to the TClass anyway in order to
6633 // preserve the opaque typedefs (Double32_t)
6634 if (!alias && def != nullptr)
6635 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6636 else
6637 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6638 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6639 // We now need to update the state and bits.
6640 if (cl->fState != TClass::kHasTClassInit) {
6641 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6643 }
6644 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6645 } else {
6646 delete ((TClingClassInfo *)cl->fClassInfo);
6647 cl->fClassInfo = nullptr;
6648 }
6649 }
6650}
6651
6652////////////////////////////////////////////////////////////////////////////////
6653/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6654void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6655{
6656 const TagDecl *td = dyn_cast<TagDecl>(ND);
6657 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6658 const NamedDecl *canon = nullptr;
6659
6660 std::string name;
6661 TagDecl* tdDef = nullptr;
6662 if (td) {
6663 canon = tdDef = td->getDefinition();
6664 // Let's pass the decl to the TClass only if it has a definition.
6665 if (!tdDef) return;
6666
6667 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6668 // Ignore incomplete definition.
6669 // Ignore declaration within a function.
6670 return;
6671 }
6672
6673 auto declName = tdDef->getNameAsString();
6674 // Check if we have registered the unqualified name into the list
6675 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6676 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6677 // the unqualified name is sufficient (and the fully qualified name might be
6678 // 'wrong' if there is difference in spelling in the template paramters (for example)
6679 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6680 // 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() );
6681 return;
6682 }
6683
6684 clang::QualType type(tdDef->getTypeForDecl(), 0);
6686 } else if (ns) {
6687 canon = ns->getCanonicalDecl();
6688 name = ND->getQualifiedNameAsString();
6689 } else {
6690 name = ND->getQualifiedNameAsString();
6691 }
6692
6693 // Supposedly we are being called while something is being
6694 // loaded ... let's now tell the autoloader to do the work
6695 // yet another time.
6696 SuspendAutoLoadingRAII autoLoadOff(this);
6697 // FIXME: There can be more than one TClass for a single decl.
6698 // for example vector<double> and vector<Double32_t>
6699 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6700 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6701 RefreshClassInfo(cl, canon, false);
6702 }
6703 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6704 // and update them too:
6705 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6706 // RefreshClassInfo(cl, tdDef, true);
6707}
6708
6709////////////////////////////////////////////////////////////////////////////////
6710/// No op: see TClingCallbacks
6711
6712void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6713{
6714}
6715
6716//______________________________________________________________________________
6717//FIXME: Factor out that function in TClass, because TClass does it already twice
6718void TCling::UpdateClassInfoWork(const char* item)
6719{
6720 // This is a no-op as part of the API.
6721 // TCling uses UpdateClassInfoWithDecl() instead.
6722}
6723
6724////////////////////////////////////////////////////////////////////////////////
6725/// Update all canvases at end the terminal input command.
6726
6728{
6729 TIter next(gROOT->GetListOfCanvases());
6730 TVirtualPad* canvas;
6731 while ((canvas = (TVirtualPad*)next())) {
6732 canvas->Update();
6733 }
6734}
6735
6736////////////////////////////////////////////////////////////////////////////////
6737
6738void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6739 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6740
6741 // If the transaction does not contain anything we can return earlier.
6742 if (!HandleNewTransaction(T)) return;
6743
6744 bool isTUTransaction = false;
6745 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6746 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6747 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6748 // The is the first transaction, we have to expose to meta
6749 // what's already in the AST.
6750 isTUTransaction = true;
6751 }
6752 }
6753
6754 std::set<const void*> TransactionDeclSet;
6755 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6756 const clang::Decl* WrapperFD = T.getWrapperFD();
6757 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6758 I != E; ++I) {
6759 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6760 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6761 continue;
6762
6763 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6764 DE = I->m_DGR.end(); DI != DE; ++DI) {
6765 if (*DI == WrapperFD)
6766 continue;
6767 TransactionDeclSet.insert(*DI);
6768 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6769 }
6770 }
6771 }
6772
6773 // The above might trigger more decls to be deserialized.
6774 // Thus the iteration over the deserialized decls must be last.
6775 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6776 E = T.deserialized_decls_end(); I != E; ++I) {
6777 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6778 DE = I->m_DGR.end(); DI != DE; ++DI)
6779 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6780 //FIXME: HandleNewDecl should take DeclGroupRef
6781 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6782 modifiedTClasses);
6783 }
6784 }
6785
6786
6787 // When fully building the reflection info in TClass, a deserialization
6788 // could be triggered, which may result in request for building the
6789 // reflection info for the same TClass. This in turn will clear the caches
6790 // for the TClass in-flight and cause null ptr derefs.
6791 // FIXME: This is a quick fix, solving most of the issues. The actual
6792 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6793 // itself until the update is done.
6794 //
6795 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6796 std::vector<TClass*>::iterator it;
6797 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6798 ((TCling*)gCling)->GetModTClasses().begin(),
6799 ((TCling*)gCling)->GetModTClasses().end(),
6800 modifiedTClassesDiff.begin());
6801 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6802
6803 // Lock the TClass for updates
6804 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6805 modifiedTClassesDiff.end());
6806 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6807 E = modifiedTClassesDiff.end(); I != E; ++I) {
6808 // Make sure the TClass has not been deleted.
6809 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6810 continue;
6811 }
6812 // Could trigger deserialization of decls.
6813 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6814 // Unlock the TClass for updates
6815 ((TCling*)gCling)->GetModTClasses().erase(*I);
6816
6817 }
6818}
6819
6820///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6821///
6822void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6823{
6825
6826 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6827 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6828 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6829 (TListOfEnums *)gROOT->GetListOfEnums());
6830
6831 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6832 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6833 I != E; ++I) {
6834 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6835 continue;
6836 if (I->m_Call == cling::Transaction::kCCINone) {
6837 UpdateListsOnUnloaded(*(*iNested));
6838 ++iNested;
6839 continue;
6840 }
6841
6842 for (auto &D : I->m_DGR)
6843 InvalidateCachedDecl(Lists, D);
6844 }
6845}
6846
6847///\brief Invalidate cached TCling information for the given global declaration.
6848///
6849void TCling::InvalidateGlobal(const Decl *D) {
6850 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6851 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6852 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6853 (TListOfEnums *)gROOT->GetListOfEnums());
6854 InvalidateCachedDecl(Lists, D);
6855}
6856
6857///\brief Invalidate cached TCling information for the given declaration, and
6858/// removed it from the appropriate object list.
6859///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6860/// TListOfFunctionTemplates&, TListOfEnums&>
6861/// of pointers to the (global/class) object lists.
6862///\param[in] D - Decl to discard.
6863///
6867 TListOfEnums*> &Lists, const Decl *D) {
6868 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6869 return;
6870
6871 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6872 TListOfFunctions &LOF = *(std::get<1>(Lists));
6873 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6874 TListOfEnums &LOE = *(std::get<3>(Lists));
6875
6876 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6877 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6878 if (LODM.GetClass())
6879 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6880 else
6881 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6882 } else if (isa<FunctionDecl>(D)) {
6884 } else if (isa<FunctionTemplateDecl>(D)) {
6886 } else if (isa<EnumDecl>(D)) {
6887 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6888 if (!E)
6889 return;
6890
6891 // Try to invalidate enumerators (for unscoped enumerations).
6892 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6894 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6895
6897 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6898 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6899 return;
6900
6901 std::vector<TClass *> Classes;
6902 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6903 return;
6904 for (auto &C : Classes) {
6905 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6906 (TListOfFunctions *)C->GetListOfMethods(),
6907 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6908 (TListOfEnums *)C->GetListOfEnums());
6909 for (auto &I : cast<DeclContext>(D)->decls())
6910 InvalidateCachedDecl(Lists, I);
6911
6912 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6913 if (D->getKind() != Decl::Namespace
6914 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6915 C->ResetClassInfo();
6916 }
6917 }
6918}
6919
6920////////////////////////////////////////////////////////////////////////////////
6921// If an autoparse was done during a transaction and that it is rolled back,
6922// we need to make sure the next request for the same autoparse will be
6923// honored.
6924void TCling::TransactionRollback(const cling::Transaction &T) {
6925 auto const &triter = fTransactionHeadersMap.find(&T);
6926 if (triter != fTransactionHeadersMap.end()) {
6927 std::size_t normNameHash = triter->second;
6928
6929 fLookedUpClasses.erase(normNameHash);
6930
6931 auto const &iter = fClassesHeadersMap.find(normNameHash);
6932 if (iter != fClassesHeadersMap.end()) {
6933 auto const &hNamesPtrs = iter->second;
6934 for (auto &hName : hNamesPtrs) {
6935 if (gDebug > 0) {
6936 Info("TransactionRollback",
6937 "Restoring ability to autoaparse: %s", hName);
6938 }
6939 fParsedPayloadsAddresses.erase(hName);
6940 }
6941 }
6942 }
6943}
6944
6945////////////////////////////////////////////////////////////////////////////////
6946
6947void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6948// R__LOCKGUARD_CLING(gInterpreterMutex);
6949// UpdateListOfLoadedSharedLibraries();
6950}
6951
6952////////////////////////////////////////////////////////////////////////////////
6953
6954void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6955 fPrevLoadedDynLibInfo = nullptr;
6956 fSharedLibs = "";
6957}
6958
6959////////////////////////////////////////////////////////////////////////////////
6960/// Return the list of shared libraries loaded into the process.
6961
6963{
6966 return fSharedLibs;
6967}
6968
6969static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
6970{
6971 if (!cls || !*cls)
6972 return {};
6973
6974 using namespace clang;
6975 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6976 /*type*/ nullptr, /*instantiate*/ false)) {
6977 if (!D->isFromASTFile()) {
6978 if (gDebug > 5)
6979 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6980 return {};
6981 }
6982 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6983 llvm::DenseSet<Module *> &m_TopLevelModules;
6984
6985 public:
6986 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6987 void Collect(const Decl *D) { Visit(D); }
6988
6989 void VisitDecl(const Decl *D)
6990 {
6991 // FIXME: Such case is described ROOT-7765 where
6992 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6993 // They are specified as #includes in the LinkDef file. This leads to
6994 // generation of incomplete modulemap files and this logic fails to
6995 // compute the corresponding module of D.
6996 // FIXME: If we want to support such a case, we should not rely on
6997 // the contents of the modulemap but mangle D and look it up in the
6998 // .so files.
6999 if (!D->hasOwningModule())
7000 return;
7001 if (Module *M = D->getOwningModule()->getTopLevelModule())
7002 m_TopLevelModules.insert(M);
7003 }
7004
7005 void VisitTemplateArgument(const TemplateArgument &TA)
7006 {
7007 switch (TA.getKind()) {
7008 case TemplateArgument::Null:
7009 case TemplateArgument::Integral:
7010 case TemplateArgument::Pack:
7011 case TemplateArgument::NullPtr:
7012 case TemplateArgument::Expression:
7013 case TemplateArgument::Template:
7014 case TemplateArgument::TemplateExpansion: return;
7015 case TemplateArgument::Type:
7016 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7017 return Visit(TagTy->getDecl());
7018 return;
7019 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7020 }
7021 llvm_unreachable("Invalid TemplateArgument::Kind!");
7022 }
7023
7024 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7025 {
7026 if (CTSD->getOwningModule())
7027 VisitDecl(CTSD);
7028 else
7029 VisitDecl(CTSD->getSpecializedTemplate());
7030 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7031 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7032 VisitTemplateArgument(*Arg);
7033 }
7034 }
7035 };
7036
7037 llvm::DenseSet<Module *> TopLevelModules;
7038 ModuleCollector m(TopLevelModules);
7039 m.Collect(D);
7040 std::string result;
7041 for (auto M : TopLevelModules) {
7042 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7043 // link declaration.
7044 if (!M->LinkLibraries.size())
7045 continue;
7046 // We have preloaded the Core module thus libCore.so
7047 if (M->Name == "Core" && skipCore)
7048 continue;
7049 assert(M->LinkLibraries.size() == 1);
7050 if (!result.empty())
7051 result += ' ';
7052 result += M->LinkLibraries[0].Library;
7053 }
7054 return result;
7055 }
7056 return {};
7057}
7058
7059////////////////////////////////////////////////////////////////////////////////
7060/// Get the list of shared libraries containing the code for class cls.
7061/// The first library in the list is the one containing the class, the
7062/// others are the libraries the first one depends on. Returns 0
7063/// in case the library is not found.
7064/// \param cls the name of the class
7065/// \param skipCore if true (default), remove "Core" from the returned list
7066
7067const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7068{
7069 if (fCxxModulesEnabled) {
7070 // Lock the interpreter mutex before interacting with cling.
7071 // TODO: Can we move this further deep? In principle the lock should be in
7072 // GetClassSharedLibsForModule, but it might be needed also for
7073 // getLookupHelper?
7075 llvm::StringRef className = cls;
7076 // If we get a class name containing lambda, we cannot parse it and we
7077 // can exit early.
7078 // FIXME: This works around a bug when we are instantiating a template
7079 // make_unique and the substitution fails. Seen in most of the dataframe
7080 // tests.
7081 if (className.contains("(lambda)"))
7082 return nullptr;
7083 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7084 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7085 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7086 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7087 if (!libs.empty()) {
7088 fAutoLoadLibStorage.push_back(libs);
7089 return fAutoLoadLibStorage.back().c_str();
7090 }
7091 }
7092
7093 if (!cls || !*cls) {
7094 return nullptr;
7095 }
7096 // lookup class to find list of libraries
7097 if (fMapfile) {
7098 TEnvRec* libs_record = nullptr;
7099 libs_record = fMapfile->Lookup(cls);
7100 if (libs_record) {
7101 const char* libs = libs_record->GetValue();
7102 return (*libs) ? libs : nullptr;
7103 }
7104 else {
7105 // Try the old format...
7106 TString c = TString("Library.") + cls;
7107 // convert "::" to "@@", we used "@@" because TEnv
7108 // considers "::" a terminator
7109 c.ReplaceAll("::", "@@");
7110 // convert "-" to " ", since class names may have
7111 // blanks and TEnv considers a blank a terminator
7112 c.ReplaceAll(" ", "-");
7113 // Use TEnv::Lookup here as the rootmap file must start with Library.
7114 // and do not support using any stars (so we do not need to waste time
7115 // with the search made by TEnv::GetValue).
7116 TEnvRec* libs_record = nullptr;
7117 libs_record = fMapfile->Lookup(c);
7118 if (libs_record) {
7119 const char* libs = libs_record->GetValue();
7120 return (*libs) ? libs : nullptr;
7121 }
7122 }
7123 }
7124 return nullptr;
7125}
7126
7127/// This interface returns a list of dependent libraries in the form:
7128/// lib libA.so libB.so libC.so. The first library is the library we are
7129/// searching dependencies for.
7130/// Note: In order to speed up the search, we display the dependencies of the
7131/// libraries which are not yet loaded. For instance, if libB.so was already
7132/// loaded the list would contain: lib libA.so libC.so.
7133static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7134 cling::Interpreter *interp,
7135 bool skipLoadedLibs = true)
7136{
7137 TString LibFullPath(lib);
7138 if (!llvm::sys::path::is_absolute(lib)) {
7139 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7140 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7141 return "";
7142 }
7143 } else {
7144 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7145 lib = llvm::sys::path::filename(lib).str();
7146 }
7147
7148 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7149 if (!ObjF) {
7150 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7151 return "";
7152 }
7153
7154 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7155
7156 std::set<string> DedupSet;
7157 std::string Result = lib + ' ';
7158 for (const auto &S : BinObjFile->symbols()) {
7159 uint32_t Flags = llvm::cantFail(S.getFlags());
7160 // Skip defined symbols: we have them.
7161 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7162 continue;
7163 // Skip undefined weak symbols: if we don't have them we won't need them.
7164 // `__gmon_start__` being a typical example.
7165 if (Flags & llvm::object::SymbolRef::SF_Weak)
7166 continue;
7167 llvm::Expected<StringRef> SymNameErr = S.getName();
7168 if (!SymNameErr) {
7169 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7170 continue;
7171 }
7172 llvm::StringRef SymName = SymNameErr.get();
7173 if (SymName.empty())
7174 continue;
7175
7176 if (BinObjFile->isELF()) {
7177 // Skip the symbols which are part of the C/C++ runtime and have a
7178 // fixed library version. See binutils ld VERSION. Those reside in
7179 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7180 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7181 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7182 continue;
7183
7184 // Those are 'weak undefined' symbols produced by gcc. We can
7185 // ignore them.
7186 // FIXME: It is unclear whether we can ignore all weak undefined
7187 // symbols:
7188 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7189 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7190 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7191 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7192 if (SymName == RegisterClasses ||
7193 SymName == RegisterCloneTable ||
7194 SymName == DeregisterCloneTable)
7195 continue;
7196 }
7197
7198 // If we can find the address of the symbol, we have loaded it. Skip.
7199 if (skipLoadedLibs) {
7200 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7201 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7202 continue;
7203 }
7204
7206 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7207 // The expected output is just filename without the full path, which
7208 // is not very accurate, because our Dyld implementation might find
7209 // a match in location a/b/c.so and if we return just c.so ROOT might
7210 // resolve it to y/z/c.so and there we might not be ABI compatible.
7211 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7212 if (!found.empty()) {
7213 std::string cand = llvm::sys::path::filename(found).str();
7214 if (!DedupSet.insert(cand).second)
7215 continue;
7216
7217 Result += cand + ' ';
7218 }
7219 }
7220
7221 return Result;
7222}
7223
7224static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7225{
7226 // Check if we have parsed a rootmap file.
7227 llvm::SmallString<256> rootmapName;
7228 if (!lib.startswith("lib"))
7229 rootmapName.append("lib");
7230
7231 rootmapName.append(llvm::sys::path::filename(lib));
7232 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7233
7234 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7235 return true;
7236
7237 // Perform a last resort by dropping the lib prefix.
7238 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7239 if (rootmapNameNoLib.consume_front("lib"))
7240 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7241
7242 return false;
7243}
7244
7245static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7246{
7247 if (gCling->HasPCMForLibrary(lib.data()))
7248 return true;
7249
7250 return hasParsedRootmapForLibrary(lib);
7251}
7252
7253////////////////////////////////////////////////////////////////////////////////
7254/// Get the list a libraries on which the specified lib depends. The
7255/// returned string contains as first element the lib itself.
7256/// Returns 0 in case the lib does not exist or does not have
7257/// any dependencies. If useDyld is true, we iterate through all available
7258/// libraries and try to construct the dependency chain by resolving each
7259/// symbol.
7260
7261const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7262{
7263 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7264 return nullptr;
7265
7266 if (!hasParsedRootmapForLibrary(lib)) {
7267 llvm::SmallString<512> rootmapName(lib);
7268 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7269 if (llvm::sys::fs::exists(rootmapName)) {
7270 if (gDebug > 0)
7271 Info("Load", "loading %s", rootmapName.c_str());
7272 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7273 }
7274 }
7275
7276 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7277 if (gDebug > 0)
7278 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7279 }
7280
7281 if (useDyld) {
7282 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7283 if (!libs.empty()) {
7284 fAutoLoadLibStorage.push_back(libs);
7285 return fAutoLoadLibStorage.back().c_str();
7286 }
7287 }
7288
7289 if (!fMapfile || !lib || !lib[0]) {
7290 return nullptr;
7291 }
7292 TString libname(lib);
7293 Ssiz_t idx = libname.Last('.');
7294 if (idx != kNPOS) {
7295 libname.Remove(idx);
7296 }
7297 TEnvRec* rec;
7298 TIter next(fMapfile->GetTable());
7299 size_t len = libname.Length();
7300 while ((rec = (TEnvRec*) next())) {
7301 const char* libs = rec->GetValue();
7302 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7303 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7304 return libs;
7305 }
7306 }
7307 return nullptr;
7308}
7309
7310////////////////////////////////////////////////////////////////////////////////
7311/// If error messages are disabled, the interpreter should suppress its
7312/// failures and warning messages from stdout.
7313
7315{
7316#if defined(R__MUST_REVISIT)
7317#if R__MUST_REVISIT(6,2)
7318 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7319#endif
7320#endif
7321 return kTRUE;
7322}
7323
7324////////////////////////////////////////////////////////////////////////////////
7325/// If error messages are disabled, the interpreter should suppress its
7326/// failures and warning messages from stdout. Return the previous state.
7327
7329{
7330#if defined(R__MUST_REVISIT)
7331#if R__MUST_REVISIT(6,2)
7332 Warning("SetErrorMessages", "Interface not available yet.");
7333#endif
7334#endif
7336}
7337
7338////////////////////////////////////////////////////////////////////////////////
7339/// Refresh the list of include paths known to the interpreter and return it
7340/// with -I prepended.
7341
7343{
7345
7346 fIncludePath = "";
7347
7348 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7349 //false - no system header, true - with flags.
7350 fInterpreter->GetIncludePaths(includePaths, false, true);
7351 if (const size_t nPaths = includePaths.size()) {
7352 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7353
7354 for (size_t i = 0; i < nPaths; i += 2) {
7355 if (i)
7356 fIncludePath.Append(' ');
7357 fIncludePath.Append(includePaths[i].c_str());
7358
7359 if (includePaths[i] != "-I")
7360 fIncludePath.Append(' ');
7361 fIncludePath.Append('"');
7362 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7363 fIncludePath.Append('"');
7364 }
7365 }
7366
7367 return fIncludePath;
7368}
7369
7370////////////////////////////////////////////////////////////////////////////////
7371/// Return the directory containing CINT's stl cintdlls.
7372
7373const char* TCling::GetSTLIncludePath() const
7374{
7375 return "";
7376}
7377
7378//______________________________________________________________________________
7379// M I S C
7380//______________________________________________________________________________
7381
7382int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7383{
7384 // Interface to cling function
7385 return 0;
7386}
7387
7388////////////////////////////////////////////////////////////////////////////////
7389/// Interface to cling function
7390
7391int TCling::DisplayIncludePath(FILE *fout) const
7392{
7393 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7394
7395 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7396 //false - no system header, true - with flags.
7397 fInterpreter->GetIncludePaths(includePaths, false, true);
7398 if (const size_t nPaths = includePaths.size()) {
7399 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7400
7401 std::string allIncludes("include path:");
7402 for (size_t i = 0; i < nPaths; i += 2) {
7403 allIncludes += ' ';
7404 allIncludes += includePaths[i];
7405
7406 if (includePaths[i] != "-I")
7407 allIncludes += ' ';
7408 allIncludes += includePaths[i + 1];
7409 }
7410
7411 fprintf(fout, "%s\n", allIncludes.c_str());
7412 }
7413
7414 return 0;
7415}
7416
7417////////////////////////////////////////////////////////////////////////////////
7418/// Interface to cling function
7419
7420void* TCling::FindSym(const char* entry) const
7421{
7423 return fInterpreter->getAddressOfGlobal(entry);
7424}
7425
7426////////////////////////////////////////////////////////////////////////////////
7427/// Let the interpreter issue a generic error, and set its error state.
7428
7429void TCling::GenericError(const char* error) const
7430{
7431#if defined(R__MUST_REVISIT)
7432#if R__MUST_REVISIT(6,2)
7433 Warning("GenericError","Interface not available yet.");
7434#endif
7435#endif
7436}
7437
7438////////////////////////////////////////////////////////////////////////////////
7439/// This routines used to return the address of the internal wrapper
7440/// function (of the interpreter) that was used to call *all* the
7441/// interpreted functions that were bytecode compiled (no longer
7442/// interpreted line by line). In Cling, there is no such
7443/// wrapper function.
7444/// In practice this routines was use to decipher whether the
7445/// pointer returns by InterfaceMethod could be used to uniquely
7446/// represent the function. In Cling if the function is in a
7447/// useable state (its compiled version is available), this is
7448/// always the case.
7449/// See TClass::GetMethod.
7450
7452{
7453 return 0;
7454}
7455
7456////////////////////////////////////////////////////////////////////////////////
7457/// Interface to cling function
7458
7460{
7461#if defined(R__MUST_REVISIT)
7462#if R__MUST_REVISIT(6,2)
7463 Warning("GetSecurityError", "Interface not available yet.");
7464#endif
7465#endif
7466 return 0;
7467}
7468
7469////////////////////////////////////////////////////////////////////////////////
7470/// Load a source file or library called path into the interpreter.
7471
7472int TCling::LoadFile(const char* path) const
7473{
7474 // Modifying the interpreter state needs locking.
7476 cling::Interpreter::CompilationResult compRes;
7477 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7478 return compRes == cling::Interpreter::kFailure;
7479}
7480
7481////////////////////////////////////////////////////////////////////////////////
7482/// Load the declarations from text into the interpreter.
7483/// Note that this cannot be (top level) statements; text must contain
7484/// top level declarations.
7485/// Returns true on success, false on failure.
7486
7487Bool_t TCling::LoadText(const char* text) const
7488{
7489 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7490}
7491
7492////////////////////////////////////////////////////////////////////////////////
7493/// Interface to cling function
7494
7495const char* TCling::MapCppName(const char* name) const
7496{
7497 TTHREAD_TLS_DECL(std::string,buffer);
7499 return buffer.c_str(); // NOLINT
7500}
7501
7502////////////////////////////////////////////////////////////////////////////////
7503/// [Place holder for Mutex Lock]
7504/// Provide the interpreter with a way to
7505/// acquire a lock used to protect critical section
7506/// of its code (non-thread safe parts).
7507
7508void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7509{
7510 // nothing to do for now.
7511}
7512
7513////////////////////////////////////////////////////////////////////////////////
7514/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7515/// release a lock used to protect critical section
7516/// of its code (non-thread safe parts).
7517
7518void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7519{
7520 // nothing to do for now.
7521}
7522
7523////////////////////////////////////////////////////////////////////////////////
7524/// Returns if class AutoLoading is currently enabled.
7525
7527{
7528 if (IsFromRootCling())
7529 return false;
7530 if (!fClingCallbacks)
7531 return false;
7533}
7534
7535////////////////////////////////////////////////////////////////////////////////
7536/// Enable/Disable the AutoLoading of libraries.
7537/// Returns the old value, i.e whether it was enabled or not.
7538
7539int TCling::SetClassAutoLoading(int autoload) const
7540{
7541 // If no state change is required, exit early.
7542 // FIXME: In future we probably want to complain if we made a request which
7543 // was with the same state as before in order to catch programming errors.
7544 if ((bool) autoload == IsClassAutoLoadingEnabled())
7545 return autoload;
7546
7547 assert(fClingCallbacks && "We must have callbacks!");
7548 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7550 return oldVal;
7551}
7552
7553////////////////////////////////////////////////////////////////////////////////
7554/// Enable/Disable the Autoparsing of headers.
7555/// Returns the old value, i.e whether it was enabled or not.
7556
7558{
7559 bool oldVal = fHeaderParsingOnDemand;
7560 fHeaderParsingOnDemand = autoparse;
7561 return oldVal;
7562}
7563
7564////////////////////////////////////////////////////////////////////////////////
7565/// Suspend the Autoparsing of headers.
7566/// Returns the old value, i.e whether it was suspended or not.
7567
7572 return old;
7573}
7574
7575////////////////////////////////////////////////////////////////////////////////
7576/// Set a callback to receive error messages.
7577
7579{
7580#if defined(R__MUST_REVISIT)
7581#if R__MUST_REVISIT(6,2)
7582 Warning("SetErrmsgcallback", "Interface not available yet.");
7583#endif
7584#endif
7585}
7586
7588{
7589 if (enable) {
7590 auto consumer = new TClingDelegateDiagnosticPrinter(
7591 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7592 fInterpreter->getCI()->getLangOpts(),
7593 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7594 if (Level == clang::DiagnosticsEngine::Warning) {
7595 ::Warning("cling", "%s", Info.c_str());
7596 } else if (Level == clang::DiagnosticsEngine::Error
7597 || Level == clang::DiagnosticsEngine::Fatal) {
7598 ::Error("cling", "%s", Info.c_str());
7599 } else {
7600 ::Info("cling", "%s", Info.c_str());
7601 }
7602 });
7603 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7604 } else {
7605 fInterpreter->replaceDiagnosticConsumer(nullptr);
7606 }
7607}
7608
7609
7610////////////////////////////////////////////////////////////////////////////////
7611/// Create / close a scope for temporaries. No-op for cling; use
7612/// cling::Value instead.
7613
7614void TCling::SetTempLevel(int val) const
7615{
7616}
7617
7618////////////////////////////////////////////////////////////////////////////////
7619
7620int TCling::UnloadFile(const char* path) const
7621{
7622 // Modifying the interpreter state needs locking.
7624 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7625 std::string canonical = DLM->lookupLibrary(path);
7626 if (canonical.empty()) {
7627 canonical = path;
7628 }
7629 // Unload a shared library or a source file.
7630 cling::Interpreter::CompilationResult compRes;
7631 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7632 return compRes == cling::Interpreter::kFailure;
7633}
7634
7635std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7636 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7637}
7638
7639////////////////////////////////////////////////////////////////////////////////
7640/// The call to Cling's tab complition.
7641
7642void TCling::CodeComplete(const std::string& line, size_t& cursor,
7643 std::vector<std::string>& completions)
7644{
7645 fInterpreter->codeComplete(line, cursor, completions);
7646}
7647
7648////////////////////////////////////////////////////////////////////////////////
7649/// Get the interpreter value corresponding to the statement.
7651{
7652 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7653 auto compRes = fInterpreter->evaluate(code, *V);
7654 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7655}
7656
7657////////////////////////////////////////////////////////////////////////////////
7658
7660{
7661 using namespace cling;
7662 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7664}
7665
7666////////////////////////////////////////////////////////////////////////////////
7667/// Register value as a temporary, extending its lifetime to that of the
7668/// interpreter. This is needed for TCling's compatibility interfaces
7669/// returning long - the address of the temporary objects.
7670/// As such, "simple" types don't need to be stored; they are returned by
7671/// value; only pointers / references / objects need to be stored.
7672
7673void TCling::RegisterTemporary(const cling::Value& value)
7674{
7675 if (value.isValid() && value.needsManagedAllocation()) {
7677 fTemporaries->push_back(value);
7678 }
7679}
7680
7681////////////////////////////////////////////////////////////////////////////////
7682/// If the interpreter encounters Name, check whether that is an object ROOT
7683/// could retrieve. To not re-read objects from disk, cache the name/object
7684/// pair for a given LookupCtx.
7685
7686TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7687{
7688 // The call to FindSpecialObject might induces any kind of use
7689 // of the interpreter ... (library loading, function calling, etc.)
7690 // ... and we _know_ we are in the middle of parsing, so let's make
7691 // sure to save the state and then restore it.
7692
7693 if (gDirectory) {
7694 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7695 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7696 auto iSpecObj = iSpecObjMap->second.find(Name);
7697 if (iSpecObj != iSpecObjMap->second.end()) {
7698 LookupCtx = gDirectory;
7699 return iSpecObj->second;
7700 }
7701 }
7702 }
7703
7704 // Save state of the PP
7705 Sema &SemaR = fInterpreter->getSema();
7706 ASTContext& C = SemaR.getASTContext();
7707 Preprocessor &PP = SemaR.getPreprocessor();
7708 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7709 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7710 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7711 // After we have saved the token reset the current one to something which
7712 // is safe (semi colon usually means empty decl)
7713 Token& Tok = const_cast<Token&>(P.getCurToken());
7714 Tok.setKind(tok::semi);
7715
7716 // We can't PushDeclContext, because we go up and the routine that pops
7717 // the DeclContext assumes that we drill down always.
7718 // We have to be on the global context. At that point we are in a
7719 // wrapper function so the parent context must be the global.
7720 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7721 SemaR.TUScope);
7722
7723 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7724 if (specObj) {
7725 if (!LookupCtx) {
7726 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7727 } else {
7728 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7729 }
7730 }
7731 return specObj;
7732}
7733
7734////////////////////////////////////////////////////////////////////////////////
7735/// Inject function as a friend into klass.
7736/// With function being f in void f() {new N::PrivKlass(); } this enables
7737/// I/O of non-public classes.
7738
7739void TCling::AddFriendToClass(clang::FunctionDecl* function,
7740 clang::CXXRecordDecl* klass) const
7741{
7742 using namespace clang;
7743 ASTContext& Ctx = klass->getASTContext();
7744 FriendDecl::FriendUnion friendUnion(function);
7745 // one dummy object for the source location
7746 SourceLocation sl;
7747 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7748 klass->pushFriendDecl(friendDecl);
7749}
7750
7751//______________________________________________________________________________
7752//
7753// DeclId getter.
7754//
7755
7756////////////////////////////////////////////////////////////////////////////////
7757/// Return a unique identifier of the declaration represented by the
7758/// CallFunc
7759
7761{
7762 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7763 return nullptr;
7764}
7765
7766////////////////////////////////////////////////////////////////////////////////
7767/// Return a (almost) unique identifier of the declaration represented by the
7768/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7769/// when the underlying class is a template instance involving one of the
7770/// opaque typedef.
7771
7773{
7774 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7775 return nullptr;
7776}
7777
7778////////////////////////////////////////////////////////////////////////////////
7779/// Return a unique identifier of the declaration represented by the
7780/// MethodInfo
7781
7783{
7784 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7785 return nullptr;
7786}
7787
7788////////////////////////////////////////////////////////////////////////////////
7789/// Return a unique identifier of the declaration represented by the
7790/// MethodInfo
7791
7793{
7794 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7795 return nullptr;
7796}
7797
7798////////////////////////////////////////////////////////////////////////////////
7799/// Return a unique identifier of the declaration represented by the
7800/// TypedefInfo
7801
7803{
7804 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7805 return nullptr;
7806}
7807
7808//______________________________________________________________________________
7809//
7810// CallFunc interface
7811//
7812
7813////////////////////////////////////////////////////////////////////////////////
7814
7815void TCling::CallFunc_Delete(CallFunc_t* func) const
7816{
7817 delete (TClingCallFunc*) func;
7818}
7819
7820////////////////////////////////////////////////////////////////////////////////
7821
7822void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7823{
7824 TClingCallFunc* f = (TClingCallFunc*) func;
7825 f->Exec(address);
7826}
7827
7828////////////////////////////////////////////////////////////////////////////////
7829
7830void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7831{
7832 TClingCallFunc* f = (TClingCallFunc*) func;
7833 f->Exec(address, &val);
7834}
7835
7836////////////////////////////////////////////////////////////////////////////////
7837
7838void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7839{
7840 TClingCallFunc* f = (TClingCallFunc*) func;
7841 f->ExecWithReturn(address, ret);
7842}
7843
7844////////////////////////////////////////////////////////////////////////////////
7845
7846void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7847 const void* args[] /*=0*/,
7848 int nargs /*=0*/,
7849 void* ret/*=0*/) const
7850{
7851 TClingCallFunc* f = (TClingCallFunc*) func;
7852 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7853}
7854
7855////////////////////////////////////////////////////////////////////////////////
7856
7857Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7858{
7859 TClingCallFunc* f = (TClingCallFunc*) func;
7860 return f->ExecInt(address);
7861}
7862
7863////////////////////////////////////////////////////////////////////////////////
7864
7865Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7866{
7867 TClingCallFunc* f = (TClingCallFunc*) func;
7868 return f->ExecInt64(address);
7869}
7870
7871////////////////////////////////////////////////////////////////////////////////
7872
7873Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7874{
7875 TClingCallFunc* f = (TClingCallFunc*) func;
7876 return f->ExecDouble(address);
7877}
7878
7879////////////////////////////////////////////////////////////////////////////////
7880
7881CallFunc_t* TCling::CallFunc_Factory() const
7882{
7884 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7885}
7886
7887////////////////////////////////////////////////////////////////////////////////
7888
7889CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7890{
7891 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7892}
7893
7894////////////////////////////////////////////////////////////////////////////////
7895
7896MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7897{
7898 TClingCallFunc* f = (TClingCallFunc*) func;
7899 return (MethodInfo_t*) f->FactoryMethod();
7900}
7901
7902////////////////////////////////////////////////////////////////////////////////
7903
7904void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7905{
7906 TClingCallFunc* f = (TClingCallFunc*) func;
7907 f->IgnoreExtraArgs(ignore);
7908}
7909
7910////////////////////////////////////////////////////////////////////////////////
7911
7912void TCling::CallFunc_Init(CallFunc_t* func) const
7913{
7915 TClingCallFunc* f = (TClingCallFunc*) func;
7916 f->Init();
7917}
7918
7919////////////////////////////////////////////////////////////////////////////////
7920
7921bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7922{
7923 TClingCallFunc* f = (TClingCallFunc*) func;
7924 return f->IsValid();
7925}
7926
7927////////////////////////////////////////////////////////////////////////////////
7928
7930TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7931{
7932 TClingCallFunc* f = (TClingCallFunc*) func;
7933 return f->IFacePtr();
7934}
7935
7936////////////////////////////////////////////////////////////////////////////////
7937
7938void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7939{
7940 TClingCallFunc* f = (TClingCallFunc*) func;
7941 f->ResetArg();
7942}
7943
7944////////////////////////////////////////////////////////////////////////////////
7945
7946void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7947{
7948 TClingCallFunc* f = (TClingCallFunc*) func;
7949 f->SetArg(param);
7950}
7951
7952////////////////////////////////////////////////////////////////////////////////
7953
7954void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7955{
7956 TClingCallFunc* f = (TClingCallFunc*) func;
7957 f->SetArg(param);
7958}
7959
7960////////////////////////////////////////////////////////////////////////////////
7961
7962void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7963{
7964 TClingCallFunc* f = (TClingCallFunc*) func;
7965 f->SetArg(param);
7966}
7967
7968////////////////////////////////////////////////////////////////////////////////
7969
7970void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7971{
7972 TClingCallFunc* f = (TClingCallFunc*) func;
7973 f->SetArg(param);
7974}
7975
7976////////////////////////////////////////////////////////////////////////////////
7977
7978void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7979{
7980 TClingCallFunc* f = (TClingCallFunc*) func;
7981 f->SetArg(param);
7982}
7983
7984////////////////////////////////////////////////////////////////////////////////
7985
7986void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7987{
7988 TClingCallFunc* f = (TClingCallFunc*) func;
7989 f->SetArg(param);
7990}
7991
7992////////////////////////////////////////////////////////////////////////////////
7993
7994void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
7995{
7996 TClingCallFunc* f = (TClingCallFunc*) func;
7997 f->SetArgArray(paramArr, nparam);
7998}
7999
8000////////////////////////////////////////////////////////////////////////////////
8001
8002void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8003{
8004 TClingCallFunc* f = (TClingCallFunc*) func;
8005 f->SetArgs(param);
8006}
8007
8008////////////////////////////////////////////////////////////////////////////////
8009
8010void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8011{
8012 TClingCallFunc* f = (TClingCallFunc*) func;
8013 TClingClassInfo* ci = (TClingClassInfo*) info;
8014 f->SetFunc(ci, method, params, offset);
8015}
8016
8017////////////////////////////////////////////////////////////////////////////////
8018
8019void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8020{
8021 TClingCallFunc* f = (TClingCallFunc*) func;
8022 TClingClassInfo* ci = (TClingClassInfo*) info;
8023 f->SetFunc(ci, method, params, objectIsConst, offset);
8024}
8025////////////////////////////////////////////////////////////////////////////////
8026
8027void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8028{
8029 TClingCallFunc* f = (TClingCallFunc*) func;
8030 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8031 f->SetFunc(minfo);
8032}
8033
8034////////////////////////////////////////////////////////////////////////////////
8035/// Interface to cling function
8036
8037void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8038{
8039 TClingCallFunc* f = (TClingCallFunc*) func;
8040 TClingClassInfo* ci = (TClingClassInfo*) info;
8041 f->SetFuncProto(ci, method, proto, offset, mode);
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045/// Interface to cling function
8046
8047void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8048{
8049 TClingCallFunc* f = (TClingCallFunc*) func;
8050 TClingClassInfo* ci = (TClingClassInfo*) info;
8051 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8052}
8053
8054////////////////////////////////////////////////////////////////////////////////
8055/// Interface to cling function
8056
8057void 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
8058{
8059 TClingCallFunc* f = (TClingCallFunc*) func;
8060 TClingClassInfo* ci = (TClingClassInfo*) info;
8061 llvm::SmallVector<clang::QualType, 4> funcProto;
8062 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8063 iter != end; ++iter) {
8064 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8065 }
8066 f->SetFuncProto(ci, method, funcProto, offset, mode);
8067}
8068
8069////////////////////////////////////////////////////////////////////////////////
8070/// Interface to cling function
8071
8072void 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
8073{
8074 TClingCallFunc* f = (TClingCallFunc*) func;
8075 TClingClassInfo* ci = (TClingClassInfo*) info;
8076 llvm::SmallVector<clang::QualType, 4> funcProto;
8077 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8078 iter != end; ++iter) {
8079 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8080 }
8081 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8082}
8083
8084std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8085{
8086 TClingCallFunc *f = (TClingCallFunc *)func;
8087 std::string wrapper_name;
8088 std::string wrapper;
8089 f->get_wrapper_code(wrapper_name, wrapper);
8090 return wrapper;
8091}
8092
8093//______________________________________________________________________________
8094//
8095// ClassInfo interface
8096//
8097
8098////////////////////////////////////////////////////////////////////////////////
8099/// Return true if the entity pointed to by 'declid' is declared in
8100/// the context described by 'info'. If info is null, look into the
8101/// global scope (translation unit scope).
8102
8103Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8104{
8105 if (!declid)
8106 return kFALSE;
8107
8108 const clang::DeclContext *ctxt = nullptr;
8109 if (info) {
8110 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8111 } else {
8112 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8113 }
8114 if (!ctxt)
8115 return kFALSE;
8116
8117 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8118 if (!decl)
8119 return kFALSE;
8120
8121 const clang::DeclContext *declDC = decl->getDeclContext();
8122 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8123 while (true) {
8124 if (declDC->isTransparentContext()) {
8125 declDC = declDC->getParent();
8126 continue;
8127 }
8128 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8129 if (declRD->isAnonymousStructOrUnion()) {
8130 declDC = declRD->getParent();
8131 continue;
8132 }
8133 }
8134 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8135 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8136 declDC = declNS->getParent();
8137 continue;
8138 }
8139 }
8140 break;
8141 }
8142
8143 return declDC->Equals(ctxt);
8144}
8145
8146////////////////////////////////////////////////////////////////////////////////
8147
8149{
8150 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8151 return TClinginfo->ClassProperty();
8152}
8153
8154////////////////////////////////////////////////////////////////////////////////
8155
8156void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8157{
8158 delete (TClingClassInfo*) cinfo;
8159}
8160
8161////////////////////////////////////////////////////////////////////////////////
8162
8163void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8164{
8165 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8166 TClinginfo->Delete(arena,*fNormalizedCtxt);
8167}
8168
8169////////////////////////////////////////////////////////////////////////////////
8170
8171void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8172{
8173 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8174 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8175}
8176
8177////////////////////////////////////////////////////////////////////////////////
8178
8179void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8180{
8181 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8182 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8183}
8184
8185////////////////////////////////////////////////////////////////////////////////
8186
8187ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8188{
8190 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8191}
8192
8193////////////////////////////////////////////////////////////////////////////////
8194
8195ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8196{
8197 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8198}
8199
8200////////////////////////////////////////////////////////////////////////////////
8201
8202ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8203{
8205 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8206}
8207
8208ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8209{
8211 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8212}
8213
8214
8215////////////////////////////////////////////////////////////////////////////////
8216
8217int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8218{
8219 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8220 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8221}
8222
8223////////////////////////////////////////////////////////////////////////////////
8224
8225bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8226{
8227 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8229}
8230
8231////////////////////////////////////////////////////////////////////////////////
8232
8233bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8234{
8235 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8236 return TClinginfo->HasMethod(name);
8237}
8238
8239////////////////////////////////////////////////////////////////////////////////
8240
8241void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8242{
8244 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8245 TClinginfo->Init(name);
8246}
8247
8248////////////////////////////////////////////////////////////////////////////////
8249
8250void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8251{
8253 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8254 TClinginfo->Init(tagnum);
8255}
8256
8257////////////////////////////////////////////////////////////////////////////////
8258
8259bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8260{
8261 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8262 return TClinginfo->IsBase(name);
8263}
8264
8265////////////////////////////////////////////////////////////////////////////////
8266
8267bool TCling::ClassInfo_IsEnum(const char* name) const
8268{
8270}
8271
8272////////////////////////////////////////////////////////////////////////////////
8273
8275{
8276 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8277 return TClinginfo->IsScopedEnum();
8278}
8279
8280
8281////////////////////////////////////////////////////////////////////////////////
8282
8284{
8285 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8286 return TClinginfo->GetUnderlyingType();
8287}
8288
8289
8290////////////////////////////////////////////////////////////////////////////////
8291
8292bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8293{
8294 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8295 return TClinginfo->IsLoaded();
8296}
8297
8298////////////////////////////////////////////////////////////////////////////////
8299
8300bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8301{
8302 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8303 return TClinginfo->IsValid();
8304}
8305
8306////////////////////////////////////////////////////////////////////////////////
8307
8308bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8309{
8310 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8311 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8312}
8313
8314////////////////////////////////////////////////////////////////////////////////
8315
8316bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8317{
8318 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8319 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8320}
8321
8322////////////////////////////////////////////////////////////////////////////////
8323
8324int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8325{
8326 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8327 return TClinginfo->Next();
8328}
8329
8330////////////////////////////////////////////////////////////////////////////////
8331
8332void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8333{
8334 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8335 return TClinginfo->New(*fNormalizedCtxt);
8336}
8337
8338////////////////////////////////////////////////////////////////////////////////
8339
8340void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8341{
8342 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8343 return TClinginfo->New(n,*fNormalizedCtxt);
8344}
8345
8346////////////////////////////////////////////////////////////////////////////////
8347
8348void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8349{
8350 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8351 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8352}
8353
8354////////////////////////////////////////////////////////////////////////////////
8355
8356void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8357{
8358 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8359 return TClinginfo->New(arena,*fNormalizedCtxt);
8360}
8361
8362////////////////////////////////////////////////////////////////////////////////
8363
8364Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8365{
8366 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8367 return TClinginfo->Property();
8368}
8369
8370////////////////////////////////////////////////////////////////////////////////
8371
8372int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8373{
8374 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8375 return TClinginfo->Size();
8376}
8377
8378////////////////////////////////////////////////////////////////////////////////
8379
8380Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8381{
8382 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8383 return TClinginfo->Tagnum();
8384}
8385
8386////////////////////////////////////////////////////////////////////////////////
8387
8388const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8389{
8390 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8391 return TClinginfo->FileName();
8392}
8393
8394////////////////////////////////////////////////////////////////////////////////
8395
8396const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8397{
8398 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8399 TTHREAD_TLS_DECL(std::string,output);
8400 TClinginfo->FullName(output,*fNormalizedCtxt);
8401 return output.c_str(); // NOLINT
8402}
8403
8404////////////////////////////////////////////////////////////////////////////////
8405
8406const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8407{
8408 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8409 return TClinginfo->Name();
8410}
8411
8412////////////////////////////////////////////////////////////////////////////////
8413
8414const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8415{
8416 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8417 return TClinginfo->Title();
8418}
8419
8420////////////////////////////////////////////////////////////////////////////////
8421
8422const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8423{
8424 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8425 return TClinginfo->TmpltName();
8426}
8427
8428
8429
8430//______________________________________________________________________________
8431//
8432// BaseClassInfo interface
8433//
8434
8435////////////////////////////////////////////////////////////////////////////////
8436
8437void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8438{
8439 delete(TClingBaseClassInfo*) bcinfo;
8440}
8441
8442////////////////////////////////////////////////////////////////////////////////
8443
8444BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8445{
8447 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8448 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8449}
8450
8451////////////////////////////////////////////////////////////////////////////////
8452
8453BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8454 ClassInfo_t* base) const
8455{
8457 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8458 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8459 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8460}
8461
8462////////////////////////////////////////////////////////////////////////////////
8463
8464int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8465{
8466 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8467 return TClinginfo->Next();
8468}
8469
8470////////////////////////////////////////////////////////////////////////////////
8471
8472int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8473{
8474 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8475 return TClinginfo->Next(onlyDirect);
8476}
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8480Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8481{
8482 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8483 return TClinginfo->Offset(address, isDerivedObject);
8484}
8485
8486////////////////////////////////////////////////////////////////////////////////
8487
8488Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8489{
8490 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8491 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8492 // Offset to the class itself.
8493 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8494 return 0;
8495 }
8496 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8497}
8498
8499////////////////////////////////////////////////////////////////////////////////
8500
8501Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8502{
8503 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8504 return TClinginfo->Property();
8505}
8506
8507////////////////////////////////////////////////////////////////////////////////
8508
8509ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8510{
8511 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8512 return (ClassInfo_t *)TClinginfo->GetBase();
8513}
8514
8515////////////////////////////////////////////////////////////////////////////////
8516
8517Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8518{
8519 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8520 return TClinginfo->Tagnum();
8521}
8522
8523////////////////////////////////////////////////////////////////////////////////
8524
8525const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8526{
8527 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8528 TTHREAD_TLS_DECL(std::string,output);
8529 TClinginfo->FullName(output,*fNormalizedCtxt);
8530 return output.c_str(); // NOLINT
8531}
8532
8533////////////////////////////////////////////////////////////////////////////////
8534
8535const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8536{
8537 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8538 return TClinginfo->Name();
8539}
8540
8541////////////////////////////////////////////////////////////////////////////////
8542
8543const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8544{
8545 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8546 return TClinginfo->TmpltName();
8547}
8548
8549//______________________________________________________________________________
8550//
8551// DataMemberInfo interface
8552//
8553
8554////////////////////////////////////////////////////////////////////////////////
8555
8556int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8557{
8558 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8559 return TClinginfo->ArrayDim();
8560}
8561
8562////////////////////////////////////////////////////////////////////////////////
8563
8564void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8565{
8566 delete(TClingDataMemberInfo*) dminfo;
8567}
8568
8569////////////////////////////////////////////////////////////////////////////////
8570
8571DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8572{
8574 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8575 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8576}
8577
8578////////////////////////////////////////////////////////////////////////////////
8579
8580DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8581{
8583 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8584 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8585 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8586}
8587
8588////////////////////////////////////////////////////////////////////////////////
8589
8590DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8591{
8592 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8593 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8594}
8595
8596////////////////////////////////////////////////////////////////////////////////
8597
8598bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8599{
8600 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8601 return TClinginfo->IsValid();
8602}
8603
8604////////////////////////////////////////////////////////////////////////////////
8605
8606int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8607{
8608 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8609 return TClinginfo->MaxIndex(dim);
8610}
8611
8612////////////////////////////////////////////////////////////////////////////////
8613
8614int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8615{
8616 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8617 return TClinginfo->Next();
8618}
8619
8620////////////////////////////////////////////////////////////////////////////////
8621
8622Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8623{
8624 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8625 return TClinginfo->Offset();
8626}
8627
8628////////////////////////////////////////////////////////////////////////////////
8629
8630Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8631{
8632 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8633 return TClinginfo->Property();
8634}
8635
8636////////////////////////////////////////////////////////////////////////////////
8637
8638Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8639{
8640 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8641 return TClinginfo->TypeProperty();
8642}
8643
8644////////////////////////////////////////////////////////////////////////////////
8645
8646int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8647{
8648 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8649 return TClinginfo->TypeSize();
8650}
8651
8652////////////////////////////////////////////////////////////////////////////////
8653
8654const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8655{
8656 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8657 return TClinginfo->TypeName();
8658}
8659
8660////////////////////////////////////////////////////////////////////////////////
8661
8662const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8663{
8664 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8665 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8666}
8667
8668////////////////////////////////////////////////////////////////////////////////
8669
8670const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8671{
8672 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8673 return TClinginfo->Name();
8674}
8675
8676////////////////////////////////////////////////////////////////////////////////
8677
8678const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8679{
8680 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8681 return TClinginfo->Title();
8682}
8683
8684////////////////////////////////////////////////////////////////////////////////
8685
8686const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8687{
8688 TTHREAD_TLS_DECL(std::string,result);
8689
8690 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8691 result = TClinginfo->ValidArrayIndex().str();
8692 return result.c_str(); // NOLINT
8693}
8694
8695////////////////////////////////////////////////////////////////////////////////
8696
8697void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8698{
8699 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8700 ASTContext &C = decl->getASTContext();
8701 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8702}
8703
8704//______________________________________________________________________________
8705//
8706// Function Template interface
8707//
8708
8709////////////////////////////////////////////////////////////////////////////////
8710
8711static void ConstructorName(std::string &name, const clang::Decl *decl,
8712 cling::Interpreter &interp,
8713 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8714{
8715 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8716 if (!td) return;
8717
8718 clang::QualType qualType(td->getTypeForDecl(),0);
8719 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8720 unsigned int level = 0;
8721 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8722 if (name[cursor] == '>') ++level;
8723 else if (name[cursor] == '<' && level) --level;
8724 else if (level == 0 && name[cursor] == ':') {
8725 name.erase(0,cursor+1);
8726 break;
8727 }
8728 }
8729}
8730
8731////////////////////////////////////////////////////////////////////////////////
8732
8733void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8734{
8735 output.clear();
8736
8737 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8738 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8739 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8740 }
8741 if (!FD) {
8742 Error("GetFunctionName", "NULL Decl!");
8743 return;
8744 }
8745
8746 // For using-decls, show "Derived", not "Base", i.e. use the
8747 // name of the decl context of the UsingShadowDecl (aka `decl`)
8748 // not the name of FD's decl context.
8749 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8750 {
8752
8753 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8754 {
8756 output.insert(output.begin(), '~');
8757 } else {
8758 llvm::raw_string_ostream stream(output);
8759 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8760 // Don't trigger fopen of the source file to count lines:
8761 printPolicy.AnonymousTagLocations = false;
8762 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8763 }
8764}
8765
8766////////////////////////////////////////////////////////////////////////////////
8767/// Return a unique identifier of the declaration represented by the
8768/// FuncTempInfo
8769
8771{
8772 return (DeclId_t)info;
8773}
8774
8775////////////////////////////////////////////////////////////////////////////////
8776/// Delete the FuncTempInfo_t
8777
8778void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8779{
8780 // Currently the address of ft_info is actually the decl itself,
8781 // so we have nothing to do.
8782}
8783
8784////////////////////////////////////////////////////////////////////////////////
8785/// Construct a FuncTempInfo_t
8786
8787FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8788{
8789 // Currently the address of ft_info is actually the decl itself,
8790 // so we have nothing to do.
8791
8792 return (FuncTempInfo_t*)const_cast<void*>(declid);
8793}
8794
8795////////////////////////////////////////////////////////////////////////////////
8796/// Construct a FuncTempInfo_t
8797
8798FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8799{
8800 // Currently the address of ft_info is actually the decl itself,
8801 // so we have nothing to do.
8802
8803 return (FuncTempInfo_t*)ft_info;
8804}
8805
8806////////////////////////////////////////////////////////////////////////////////
8807/// Check validity of a FuncTempInfo_t
8808
8809Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8810{
8811 // Currently the address of ft_info is actually the decl itself,
8812 // so we have nothing to do.
8813
8814 return t_info != nullptr;
8815}
8816
8817////////////////////////////////////////////////////////////////////////////////
8818/// Return the maximum number of template arguments of the
8819/// function template described by ft_info.
8820
8821UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8822{
8823 if (!ft_info) return 0;
8824 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8825 return ft->getTemplateParameters()->size();
8826}
8827
8828////////////////////////////////////////////////////////////////////////////////
8829/// Return the number of required template arguments of the
8830/// function template described by ft_info.
8831
8833{
8834 if (!ft_info) return 0;
8835 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8836 return ft->getTemplateParameters()->getMinRequiredArguments();
8837}
8838
8839////////////////////////////////////////////////////////////////////////////////
8840/// Return the property of the function template.
8841
8842Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8843{
8844 if (!ft_info) return 0;
8845
8846 long property = 0L;
8847 property |= kIsCompiled;
8848
8849 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8850
8851 switch (ft->getAccess()) {
8852 case clang::AS_public:
8853 property |= kIsPublic;
8854 break;
8855 case clang::AS_protected:
8856 property |= kIsProtected;
8857 break;
8858 case clang::AS_private:
8859 property |= kIsPrivate;
8860 break;
8861 case clang::AS_none:
8862 if (ft->getDeclContext()->isNamespace())
8864 break;
8865 default:
8866 // IMPOSSIBLE
8867 break;
8868 }
8869
8870 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8871 if (const clang::CXXMethodDecl *md =
8872 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8873 if (md->getMethodQualifiers().hasConst()) {
8874 property |= kIsConstant | kIsConstMethod;
8875 }
8876 if (md->isVirtual()) {
8877 property |= kIsVirtual;
8878 }
8879 if (md->isPure()) {
8880 property |= kIsPureVirtual;
8881 }
8882 if (const clang::CXXConstructorDecl *cd =
8883 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8884 if (cd->isExplicit()) {
8885 property |= kIsExplicit;
8886 }
8887 }
8888 else if (const clang::CXXConversionDecl *cd =
8889 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8890 if (cd->isExplicit()) {
8891 property |= kIsExplicit;
8892 }
8893 }
8894 }
8895 return property;
8896}
8897
8898////////////////////////////////////////////////////////////////////////////////
8899/// Return the property not already defined in Property
8900/// See TDictionary's EFunctionProperty
8901
8902Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8903{
8904 if (!ft_info) return 0;
8905
8906 long property = 0L;
8907 property |= kIsCompiled;
8908
8909 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8910 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8911
8912 if (fd->isOverloadedOperator())
8914 if (llvm::isa<clang::CXXConversionDecl>(fd))
8916 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8918 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8920 if (fd->isInlined())
8922 return property;
8923}
8924
8925////////////////////////////////////////////////////////////////////////////////
8926/// Return the name of this function template.
8927
8928void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8929{
8930 output.Clear();
8931 if (!ft_info) return;
8932 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8933 std::string buf;
8934 GetFunctionName(ft->getTemplatedDecl(), buf);
8935 output = buf;
8936}
8937
8938////////////////////////////////////////////////////////////////////////////////
8939/// Return the comments associates with this function template.
8940
8941void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8942{
8943 output.Clear();
8944 if (!ft_info) return;
8945 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8946
8947 // Iterate over the redeclarations, we can have multiple definitions in the
8948 // redecl chain (came from merging of pcms).
8949 if (const RedeclarableTemplateDecl *AnnotFD
8950 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8951 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8952 output = A->getAnnotation().str();
8953 return;
8954 }
8955 }
8956 if (!ft->isFromASTFile()) {
8957 // Try to get the comment from the header file if present
8958 // but not for decls from AST file, where rootcling would have
8959 // created an annotation
8961 }
8962}
8963
8964
8965//______________________________________________________________________________
8966//
8967// MethodInfo interface
8968//
8969
8970////////////////////////////////////////////////////////////////////////////////
8971/// Interface to cling function
8972
8973void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8974{
8975 delete(TClingMethodInfo*) minfo;
8976}
8977
8978////////////////////////////////////////////////////////////////////////////////
8979
8980void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8981{
8982 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8983 // The next call locks the interpreter mutex.
8984 info->CreateSignature(signature);
8985}
8986
8987////////////////////////////////////////////////////////////////////////////////
8988
8989MethodInfo_t* TCling::MethodInfo_Factory() const
8990{
8992 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8993}
8994
8995////////////////////////////////////////////////////////////////////////////////
8996
8997MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8998{
9000 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9001}
9002
9003////////////////////////////////////////////////////////////////////////////////
9004
9005MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9006{
9007 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9009 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9010}
9011
9012////////////////////////////////////////////////////////////////////////////////
9013
9014MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9015{
9016 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9017}
9018
9019////////////////////////////////////////////////////////////////////////////////
9020
9021void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9022{
9023 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9024 // The next call locks the interpreter mutex.
9025 return info->InterfaceMethod();
9026}
9027
9028////////////////////////////////////////////////////////////////////////////////
9029
9030bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9031{
9032 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9033 return info->IsValid();
9034}
9035
9036////////////////////////////////////////////////////////////////////////////////
9037
9038int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9039{
9040 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9041 return info->NArg();
9042}
9043
9044////////////////////////////////////////////////////////////////////////////////
9045
9046int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9047{
9048 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9049 return info->NDefaultArg();
9050}
9051
9052////////////////////////////////////////////////////////////////////////////////
9053
9054int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9055{
9056 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9057 return info->Next();
9058}
9059
9060////////////////////////////////////////////////////////////////////////////////
9061
9062Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9063{
9064 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9065 // The next call locks the interpreter mutex.
9066 return info->Property();
9067}
9068
9069////////////////////////////////////////////////////////////////////////////////
9070
9072{
9073 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9074 // The next call locks the interpreter mutex.
9075 return info->ExtraProperty();
9076}
9077
9078////////////////////////////////////////////////////////////////////////////////
9079
9080TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9081{
9082 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9083 // The next call locks the interpreter mutex.
9084 return (TypeInfo_t*)info->Type();
9085}
9086
9087////////////////////////////////////////////////////////////////////////////////
9088
9089const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9090{
9091 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9092 TTHREAD_TLS_DECL(TString, mangled_name);
9093 // The next call locks the interpreter mutex.
9094 mangled_name = info->GetMangledName();
9095 return mangled_name;
9096}
9097
9098////////////////////////////////////////////////////////////////////////////////
9099
9100const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9101{
9102 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9103 // The next call locks the interpreter mutex.
9104 return info->GetPrototype();
9105}
9106
9107////////////////////////////////////////////////////////////////////////////////
9108
9109const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9110{
9111 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9112 // The next call locks the interpreter mutex.
9113 return info->Name();
9114}
9115
9116////////////////////////////////////////////////////////////////////////////////
9117
9118const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9119{
9120 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9121 // The next call locks the interpreter mutex.
9122 return info->TypeName();
9123}
9124
9125////////////////////////////////////////////////////////////////////////////////
9126
9127std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9128{
9129 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9130 // The next part locks the interpreter mutex.
9131 if (info && info->IsValid())
9132 return info->Type()->NormalizedName(*fNormalizedCtxt);
9133 else
9134 return "";
9135}
9136
9137////////////////////////////////////////////////////////////////////////////////
9138
9139const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9140{
9141 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9142 // The next call locks the interpreter mutex.
9143 return info->Title();
9144}
9145
9146////////////////////////////////////////////////////////////////////////////////
9147
9149{
9150 if (func) {
9151 return MethodInfo_MethodCallReturnType(func->fInfo);
9152 } else {
9153 return EReturnType::kOther;
9154 }
9155}
9156
9157////////////////////////////////////////////////////////////////////////////////
9158
9160{
9161 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9162 if (info && info->IsValid()) {
9163 TClingTypeInfo *typeinfo = info->Type();
9164 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9165 if (QT->isEnumeralType()) {
9166 return EReturnType::kLong;
9167 } else if (QT->isPointerType()) {
9168 // Look for char*
9169 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9170 if ( QT->isCharType() ) {
9171 return EReturnType::kString;
9172 } else {
9173 return EReturnType::kOther;
9174 }
9175 } else if ( QT->isFloatingType() ) {
9176 int sz = typeinfo->Size();
9177 if (sz == 4 || sz == 8) {
9178 // Support only float and double.
9179 return EReturnType::kDouble;
9180 } else {
9181 return EReturnType::kOther;
9182 }
9183 } else if ( QT->isIntegerType() ) {
9184 int sz = typeinfo->Size();
9185 if (sz <= 8) {
9186 // Support only up to long long ... but
9187 // FIXME the TMethodCall::Execute only
9188 // return long (4 bytes) ...
9189 // The v5 implementation of TMethodCall::ReturnType
9190 // was not making the distinction so we let it go
9191 // as is for now, but we really need to upgrade
9192 // TMethodCall::Execute ...
9193 return EReturnType::kLong;
9194 } else {
9195 return EReturnType::kOther;
9196 }
9197 } else {
9198 return EReturnType::kOther;
9199 }
9200 } else {
9201 return EReturnType::kOther;
9202 }
9203}
9204
9205//______________________________________________________________________________
9206//
9207// MethodArgInfo interface
9208//
9209
9210////////////////////////////////////////////////////////////////////////////////
9211
9212void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9213{
9214 delete(TClingMethodArgInfo*) marginfo;
9215}
9216
9217////////////////////////////////////////////////////////////////////////////////
9218
9219MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9220{
9222 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9223}
9224
9225////////////////////////////////////////////////////////////////////////////////
9226
9227MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9228{
9230 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9231}
9232
9233////////////////////////////////////////////////////////////////////////////////
9234
9235MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9236{
9237 return (MethodArgInfo_t*)
9239}
9240
9241////////////////////////////////////////////////////////////////////////////////
9242
9243bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9244{
9245 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9246 return info->IsValid();
9247}
9248
9249////////////////////////////////////////////////////////////////////////////////
9250
9251int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9252{
9253 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9254 return info->Next();
9255}
9256
9257////////////////////////////////////////////////////////////////////////////////
9258
9259Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9260{
9261 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9262 return info->Property();
9263}
9264
9265////////////////////////////////////////////////////////////////////////////////
9266
9267const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9268{
9269 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9270 return info->DefaultValue();
9271}
9272
9273////////////////////////////////////////////////////////////////////////////////
9274
9275const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9276{
9277 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9278 return info->Name();
9279}
9280
9281////////////////////////////////////////////////////////////////////////////////
9282
9283const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9284{
9285 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9286 return info->TypeName();
9287}
9288
9289////////////////////////////////////////////////////////////////////////////////
9290
9291std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9292{
9293 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9294 return info->Type()->NormalizedName(*fNormalizedCtxt);
9295}
9296
9297////////////////////////////////////////////////////////////////////////////////
9298
9299TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9300{
9301 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9302 return (TypeInfo_t*) info->Type();
9303}
9304
9305//______________________________________________________________________________
9306//
9307// TypeInfo interface
9308//
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9312void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9313{
9314 delete (TClingTypeInfo*) tinfo;
9315}
9316
9317////////////////////////////////////////////////////////////////////////////////
9318
9319TypeInfo_t* TCling::TypeInfo_Factory() const
9320{
9322 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9323}
9324
9325////////////////////////////////////////////////////////////////////////////////
9326
9327TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9328{
9330 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9331}
9332
9333////////////////////////////////////////////////////////////////////////////////
9334
9335TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9336{
9337 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9338}
9339
9340////////////////////////////////////////////////////////////////////////////////
9341
9342void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9343{
9345 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9346 TClinginfo->Init(name);
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350
9351bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9352{
9353 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9354 return TClinginfo->IsValid();
9355}
9356
9357////////////////////////////////////////////////////////////////////////////////
9358
9359const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9360{
9361 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9362 return TClinginfo->Name();
9363}
9364
9365////////////////////////////////////////////////////////////////////////////////
9366
9367Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9368{
9369 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9370 return TClinginfo->Property();
9371}
9372
9373////////////////////////////////////////////////////////////////////////////////
9374
9375int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9376{
9377 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9378 return TClinginfo->RefType();
9379}
9380
9381////////////////////////////////////////////////////////////////////////////////
9382
9383int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9384{
9385 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9386 return TClinginfo->Size();
9387}
9388
9389////////////////////////////////////////////////////////////////////////////////
9390
9391const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9392{
9393 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9394 return TClinginfo->TrueName(*fNormalizedCtxt);
9395}
9396
9397////////////////////////////////////////////////////////////////////////////////
9398
9399void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9400{
9401 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9402 return TClinginfo->QualTypePtr();
9403}
9404
9405
9406//______________________________________________________________________________
9407//
9408// TypedefInfo interface
9409//
9410
9411////////////////////////////////////////////////////////////////////////////////
9412
9413void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9414{
9415 delete(TClingTypedefInfo*) tinfo;
9416}
9417
9418////////////////////////////////////////////////////////////////////////////////
9419
9420TypedefInfo_t* TCling::TypedefInfo_Factory() const
9421{
9423 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9424}
9425
9426////////////////////////////////////////////////////////////////////////////////
9427
9428TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9429{
9431 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9432}
9433
9434////////////////////////////////////////////////////////////////////////////////
9435
9436TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9437{
9438 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9439}
9440
9441////////////////////////////////////////////////////////////////////////////////
9442
9443void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9444 const char* name) const
9445{
9447 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9448 TClinginfo->Init(name);
9449}
9450
9451////////////////////////////////////////////////////////////////////////////////
9452
9453bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9454{
9455 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9456 return TClinginfo->IsValid();
9457}
9458
9459////////////////////////////////////////////////////////////////////////////////
9460
9461Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9462{
9463 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9464 return TClinginfo->Next();
9465}
9466
9467////////////////////////////////////////////////////////////////////////////////
9468
9469Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9470{
9471 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9472 return TClinginfo->Property();
9473}
9474
9475////////////////////////////////////////////////////////////////////////////////
9476
9477int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9478{
9479 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9480 return TClinginfo->Size();
9481}
9482
9483////////////////////////////////////////////////////////////////////////////////
9484
9485const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9486{
9487 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9488 return TClinginfo->TrueName(*fNormalizedCtxt);
9489}
9490
9491////////////////////////////////////////////////////////////////////////////////
9492
9493const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9494{
9495 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9496 return TClinginfo->Name();
9497}
9498
9499////////////////////////////////////////////////////////////////////////////////
9500
9501const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9502{
9503 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9504 return TClinginfo->Title();
9505}
9506
9507////////////////////////////////////////////////////////////////////////////////
9508
9509bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9510{
9511 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9512 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9513 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9514}
9515
9516////////////////////////////////////////////////////////////////////////////////
9517
9518bool TCling::IsIntegerType(const void * QualTypePtr) const
9519{
9520 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9521 return QT->hasIntegerRepresentation();
9522}
9523
9524////////////////////////////////////////////////////////////////////////////////
9525
9526bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9527{
9528 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9529 return QT->hasSignedIntegerRepresentation();
9530}
9531
9532////////////////////////////////////////////////////////////////////////////////
9533
9534bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9535{
9536 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9537 return QT->hasUnsignedIntegerRepresentation();
9538}
9539
9540////////////////////////////////////////////////////////////////////////////////
9541
9542bool TCling::IsFloatingType(const void * QualTypePtr) const
9543{
9544 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9545 return QT->hasFloatingRepresentation();
9546}
9547
9548////////////////////////////////////////////////////////////////////////////////
9549
9550bool TCling::IsPointerType(const void * QualTypePtr) const
9551{
9552 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9553 return QT->hasPointerRepresentation();
9554}
9555
9556////////////////////////////////////////////////////////////////////////////////
9557
9558bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9559{
9560 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9561 return QT->isVoidPointerType();
9562}
9563
9564////////////////////////////////////////////////////////////////////////////////
9565
9567{
9568 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9569 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9570}
9571
9572////////////////////////////////////////////////////////////////////////////////
9573
9575{
9576 if (!fInitialMutex) {
9578 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9579 }
9581 }
9582 // We will "forget" this lock once we backed out of all interpreter frames.
9583 // Here we are entering one, so ++.
9585}
9586
9587////////////////////////////////////////////////////////////////////////////////
9588
9590{
9591 if (!fInitialMutex)
9592 return;
9593 if (fInitialMutex.fRecurseCount == 0) {
9594 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9595 }
9596 else if (--fInitialMutex.fRecurseCount == 0) {
9597 // We have returned from all interpreter frames. Reset the initial lock state.
9598 fInitialMutex.fState.reset();
9599 }
9600}
9601
9602////////////////////////////////////////////////////////////////////////////////
9603/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9604
9606{
9607 if (gInterpreterMutex) {
9608 if (delta) {
9609 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9610 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9611 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9612 // Now that we have the lock, update the global
9613 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9614 std::swap(fInitialMutex, typedDelta->fInitialState);
9615 } else {
9616 // This case happens when EnableThreadSafety is first called from
9617 // the interpreter function we just handled.
9618 // Since thread safety was not enabled at the time we rewound, there was
9619 // no lock taken and even-though we should be locking the rest of this
9620 // interpreter handling/modifying code (since there might be threads in
9621 // flight), we can't because there would not be any lock guard to release the
9622 // locks
9624 Error("ApplyToInterpreterMutex",
9625 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9626 "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.");
9627 }
9628 }
9629}
9630
9631////////////////////////////////////////////////////////////////////////////////
9632/// Reset the interpreter lock to the state it had before interpreter-related
9633/// calls happened.
9634
9636{
9637 if (fInitialMutex) {
9638 // Need to start a new recurse count.
9639 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9640 std::swap(uniqueP->fInitialState, fInitialMutex);
9641 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9642 return uniqueP.release();
9643 }
9645 return nullptr;
9646}
#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
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:7224
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:8711
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:7133
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:6969
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:6309
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5489
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:7245
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:597
#define gROOT
Definition TROOT.h:407
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:488
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:277
std::atomic< TList * > fBase
Definition TClass.h:201
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx: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:205
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:332
@ kUnloading
Definition TClass.h:332
TObjArray * fStreamerInfo
Definition TClass.h:198
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
ClassInfo_t * GetClassInfo() const
Definition TClass.h:433
ClassInfo_t * fClassInfo
Definition TClass.h:222
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:126
@ kHasTClassInit
Definition TClass.h:127
@ kEmulated
Definition TClass.h:125
@ kForwardDeclared
Definition TClass.h:124
@ kNamespaceForMeta
Definition TClass.h:131
Version_t GetClassVersion() const
Definition TClass.h:420
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:259
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3463
@ kIsTObject
Definition TClass.h:100
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:6181
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9267
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8274
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9359
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9021
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4372
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:9453
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6242
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7912
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:6545
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7429
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7838
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9080
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7815
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:7472
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:8697
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:6864
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9062
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4419
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8308
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8630
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7557
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:4466
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:8300
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6738
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9375
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4348
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8187
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9109
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8444
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:7487
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7261
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9159
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7686
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:9030
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8787
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9319
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7526
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6849
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7650
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7635
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3348
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9501
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:8037
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5632
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:6500
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9566
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:4484
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:7739
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:8464
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6612
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7889
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7873
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7938
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5440
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:7904
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9605
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6568
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:4700
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:8103
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:7451
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8556
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9299
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8590
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:5505
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8324
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7578
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9243
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9383
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:7459
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7614
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:8821
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:5132
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9420
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9558
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:8372
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9283
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:5380
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8614
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9493
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8437
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9071
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:8798
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8606
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8809
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:8259
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:8654
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4927
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:7994
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8084
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9635
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9275
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:9443
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8678
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7857
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:7508
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:7328
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7896
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9534
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9436
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:5025
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:9291
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:4809
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9259
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9477
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7846
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:5177
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:6718
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:9461
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:4984
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9342
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7568
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8646
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8414
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8670
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5455
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9526
void ForgetMutexState() final
Definition TCling.cxx:9589
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9054
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8148
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:8973
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9212
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8571
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8179
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:6087
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5975
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8241
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8509
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7865
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8364
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8488
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:5362
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7314
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7391
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6924
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8842
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9391
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:5993
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7659
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6962
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9251
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9574
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9367
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9100
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:8832
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:6133
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:8980
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4326
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6947
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:8598
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8267
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9046
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4475
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5902
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:7587
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9089
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9518
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:5087
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8332
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7382
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8733
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4500
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7373
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9235
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8480
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:4154
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7420
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:9312
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9038
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4918
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9148
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:5110
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:4939
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9139
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8543
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:8525
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8002
int UnloadFile(const char *path) const final
Definition TCling.cxx:7620
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7822
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9550
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9542
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8902
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7921
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8535
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8686
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4521
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:4849
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5210
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8292
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8380
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8501
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8010
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4455
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8388
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8941
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8422
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:6604
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:7642
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:7495
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:5914
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:8564
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:5393
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:4493
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:6055
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9014
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7930
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9219
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6712
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:5006
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8156
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8283
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8778
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:5154
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:7067
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8622
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7881
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:8989
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8638
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:7518
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:9413
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:9485
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7539
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8396
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:6358
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9118
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7946
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7342
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6822
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6654
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9509
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:8217
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:4748
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:8928
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9351
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:9127
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8406
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4531
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8225
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:9335
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9399
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8233
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8171
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:8662
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:9469
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:4966
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6727
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5718
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8517
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6954
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:83
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:199
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()
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:243
void MakeZombie()
Definition TObject.h:53
@ 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:3028
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2762
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2938
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3038
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2948
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3017
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 valid name of the C++ symbol/type (pass as 'input') that can be u...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
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()