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 "clang/Interpreter/CppInterOp.h"
119
120#include "llvm/IR/GlobalValue.h"
121#include "llvm/IR/Module.h"
122
123#include "llvm/Support/DynamicLibrary.h"
124#include "llvm/Support/raw_ostream.h"
125#include "llvm/Support/Path.h"
126#include "llvm/Support/Process.h"
127#include "llvm/Object/ELFObjectFile.h"
128#include "llvm/Object/ObjectFile.h"
129#include "llvm/Object/SymbolicFile.h"
130#include "llvm/Support/FileSystem.h"
131
132#include <algorithm>
133#include <iostream>
134#include <cassert>
135#include <map>
136#include <set>
137#include <stdexcept>
138#include <stdint.h>
139#include <fstream>
140#include <sstream>
141#include <string>
142#include <tuple>
143#include <typeinfo>
144#include <unordered_map>
145#include <unordered_set>
146#include <utility>
147#include <vector>
148#include <functional>
149#include <optional>
150
151#ifndef R__WIN32
152#include <cxxabi.h>
153#define R__DLLEXPORT __attribute__ ((visibility ("default")))
154#include <sys/stat.h>
155#endif
156#include <limits.h>
157#include <stdio.h>
158
159#ifdef __APPLE__
160#include <dlfcn.h>
161#include <mach-o/dyld.h>
162#include <mach-o/loader.h>
163#endif // __APPLE__
164
165#ifdef R__UNIX
166#include <dlfcn.h>
167#endif
168
169#if defined(R__LINUX) || defined(R__FBSD)
170# ifndef _GNU_SOURCE
171# define _GNU_SOURCE
172# endif
173# include <link.h> // dl_iterate_phdr()
174#endif
175
176#if defined(__CYGWIN__)
177#include <sys/cygwin.h>
178#define HMODULE void *
179extern "C" {
181 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
182 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
183}
184#endif
185
186// Fragment copied from LLVM's raw_ostream.cpp
187#if defined(_MSC_VER)
188#ifndef STDIN_FILENO
189# define STDIN_FILENO 0
190#endif
191#ifndef STDOUT_FILENO
192# define STDOUT_FILENO 1
193#endif
194#ifndef STDERR_FILENO
195# define STDERR_FILENO 2
196#endif
197#ifndef R__WIN32
198//#if defined(HAVE_UNISTD_H)
199# include <unistd.h>
200//#endif
201#else
202#include "Windows4Root.h"
203#include <Psapi.h>
204#include <direct.h>
205#undef GetModuleFileName
206#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
207#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
208#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
209#define dlclose(library) ::FreeLibrary((HMODULE)library)
210#define R__DLLEXPORT __declspec(dllexport)
211#endif
212#endif
213
214//______________________________________________________________________________
215// These functions are helpers for debugging issues with non-LLVMDEV builds.
216//
217R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
218 return D->getDeclContext();
219}
220R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
221 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
222}
223R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
224 return llvm::dyn_cast<clang::RecordDecl>(DC);
225}
226R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
227 return DC->dumpDeclContext();
228}
229R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
230 return D->dump();
231}
232R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
233 return FD->dump();
234}
236 return ((clang::Decl*)D)->dump();
237}
239 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
240 std::string name;
241 {
242 llvm::raw_string_ostream OS(name);
243 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
244 true /*Qualified*/);
245 }
246 printf("%s\n", name.c_str());
247 }
248}
249//______________________________________________________________________________
250// These functions are helpers for testing issues directly rather than
251// relying on side effects.
252// This is used for the test for ROOT-7462/ROOT-6070
254 return D->isInvalidDecl();
255}
258 assert(info && info->IsValid());
259 return info->GetDecl()->isInvalidDecl();
260}
261
262using std::string, std::vector;
263using namespace clang;
264using namespace ROOT;
265
266namespace {
267 static const std::string gInterpreterClassDef = R"ICF(
268#undef ClassDef
269#define ClassDef(name, id) \
270_ClassDefInterp_(name,id,virtual,) \
271static int DeclFileLine() { return __LINE__; }
272#undef ClassDefNV
273#define ClassDefNV(name, id) \
274_ClassDefInterp_(name,id,,) \
275static int DeclFileLine() { return __LINE__; }
276#undef ClassDefOverride
277#define ClassDefOverride(name, id) \
278_ClassDefInterp_(name,id,,override) \
279static int DeclFileLine() { return __LINE__; }
280)ICF";
281
282 static const std::string gNonInterpreterClassDef = R"ICF(
283#define __ROOTCLING__ 1
284#undef ClassDef
285#define ClassDef(name,id) \
286_ClassDefOutline_(name,id,virtual,) \
287static int DeclFileLine() { return __LINE__; }
288#undef ClassDefNV
289#define ClassDefNV(name, id)\
290_ClassDefOutline_(name,id,,)\
291static int DeclFileLine() { return __LINE__; }
292#undef ClassDefOverride
293#define ClassDefOverride(name, id)\
294_ClassDefOutline_(name,id,,override)\
295static int DeclFileLine() { return __LINE__; }
296)ICF";
297
298// The macros below use ::Error, so let's ensure it is included
299 static const std::string gClassDefInterpMacro = R"ICF(
300#include "TError.h"
301
302#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
303private: \
304public: \
305 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
306 static const char *Class_Name() { return #name; } \
307 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
308 static Version_t Class_Version() { return id; } \
309 static TClass *Dictionary() { return 0; } \
310 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
311 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
312 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
313 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
314 static const char *DeclFileName() { return __FILE__; } \
315 static int ImplFileLine() { return 0; } \
316 static const char *ImplFileName() { return __FILE__; }
317)ICF";
318}
320
321// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
322// ROOT (which uses rtti)
323
324////////////////////////////////////////////////////////////////////////////////
325/// Print a StackTrace!
326
327extern "C"
331
332////////////////////////////////////////////////////////////////////////////////
333/// Load a library.
334
335extern "C" int TCling__LoadLibrary(const char *library)
336{
337 return gSystem->Load(library, "", false);
338}
339
340////////////////////////////////////////////////////////////////////////////////
341/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
342
343extern "C" void TCling__RestoreInterpreterMutex(void *delta)
344{
345 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
346}
347
348////////////////////////////////////////////////////////////////////////////////
349/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
350/// which is extracted by error messages we get from callback from cling. Return true
351/// when the missing library was autoloaded.
352
353extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
354{
355 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Reset the interpreter lock to the state it had before interpreter-related
360/// calls happened.
361
363{
364 return ((TCling*)gCling)->RewindInterpreterMutex();
365}
366
367////////////////////////////////////////////////////////////////////////////////
368/// Lock the interpreter.
369
371{
372 if (gInterpreterMutex) {
374 }
375 return nullptr;
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Unlock the interpreter.
380
382{
383 if (gInterpreterMutex) {
385 }
386}
387
388////////////////////////////////////////////////////////////////////////////////
389/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
390
392{
393 static Bool_t entered = kFALSE;
396
397 if (entered) topLevel = kFALSE;
398 else {
399 entered = kTRUE;
400 topLevel = kTRUE;
401 }
402 if (topLevel) {
403 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
404 } else {
405 // If we are called indirectly from within another call to
406 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
407 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
408 // This allows for the dictionary to be fully populated when we actually
409 // update the TClass object. The updating of the TClass sometimes
410 // (STL containers and when there is an emulated class) forces the building
411 // of the TClass object's real data (which needs the dictionary info).
412 updateList.push_back(TD);
413 }
414 if (topLevel) {
415 while (!updateList.empty()) {
416 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
417 updateList.pop_back();
418 }
419 entered = kFALSE;
420 }
421}
422
424 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
425 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
426 // Add the constants to the enum type.
427 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
428 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
429 // Get name of the enum type.
430 std::string constbuf;
431 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
432 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
433 llvm::raw_string_ostream stream(constbuf);
434 // Don't trigger fopen of the source file to count lines:
435 Policy.AnonymousTagLocations = false;
436 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
437 }
438 const char* constantName = constbuf.c_str();
439
440 // Get value of the constant.
442 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
443 if (valAPSInt.isSigned()) {
444 value = valAPSInt.getSExtValue();
445 } else {
446 value = valAPSInt.getZExtValue();
447 }
448
449 // Create the TEnumConstant or update it if existing
450 TEnumConstant* enumConstant = nullptr;
451 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
454 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
455 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
456 } else {
458 }
459
460 // Add the global constants to the list of Globals.
461 if (!cl) {
462 TCollection* globals = gROOT->GetListOfGlobals(false);
463 if (!globals->FindObject(constantName)) {
464 globals->Add(enumConstant);
465 }
466 }
467 }
468 }
469}
470
472{
473 // Handle new enum declaration for either global and nested enums.
474
475 // Create the enum type.
476 TEnum* enumType = nullptr;
477 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
478 std::string buf;
479 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
480 // Get name of the enum type.
481 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
482 llvm::raw_string_ostream stream(buf);
483 // Don't trigger fopen of the source file to count lines:
484 Policy.AnonymousTagLocations = false;
485 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
486 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
487 }
488 if (buf.empty()) {
489 return nullptr;
490 }
491 const char* name = buf.c_str();
492 enumType = new TEnum(name, VD, cl);
494
495 return enumType;
496}
497
498void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
499 // Handle new declaration.
500 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
501
502 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
503
504 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
505 && !dyn_cast<clang::RecordDecl>(D)) return;
506
507 if (isa<clang::FunctionDecl>(D->getDeclContext())
508 || isa<clang::TagDecl>(D->getDeclContext()))
509 return;
510
511 // Don't list templates.
512 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
513 if (RD->getDescribedClassTemplate())
514 return;
515 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
516 if (FD->getDescribedFunctionTemplate())
517 return;
518 }
519
520 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
521 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
523 }
524 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
525
526 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
527 // Mostly just for EnumDecl (the other TagDecl are handled
528 // by the 'RecordDecl' if statement.
530 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
532 }
533
534 // We care about declarations on the global scope.
535 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
536 return;
537
538 // Enums are lazyly created, thus we don not need to handle them here.
539 if (isa<EnumDecl>(ND))
540 return;
541
542 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
543 // scope.
544 if (!(isa<VarDecl>(ND)))
545 return;
546
547 // Skip if already in the list.
548 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
549 return;
550
551 // Put the global constants and global enums in the corresponding lists.
552 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
554 cast<ValueDecl>(ND), nullptr)));
555 }
556}
557
558extern "C"
560{
561 // We are sure in this context of the type of the interpreter
562 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
563}
564
565extern "C"
566void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
567 ((TCling*)gCling)->UpdateListsOnCommitted(T);
568}
569
570extern "C"
571void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
572 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
573}
574
575extern "C"
576void TCling__InvalidateGlobal(const clang::Decl *D) {
577 ((TCling*)gCling)->InvalidateGlobal(D);
578}
579
580extern "C"
581void TCling__TransactionRollback(const cling::Transaction &T) {
582 ((TCling*)gCling)->TransactionRollback(T);
583}
584
585extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
586 const char* canonicalName) {
587 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
588}
589
590extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
591{
592 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
593}
594
595extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
596 const char* canonicalName) {
597 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
598}
599
600
601extern "C"
602TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
603 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
604}
605
606extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
607 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
608}
609
611 const char* argv[])
612{
613 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
614
615 return tcling;
616}
617
619{
620 delete interp;
621}
622
623// Load library containing specified class. Returns 0 in case of error
624// and 1 in case if success.
625extern "C" int TCling__AutoLoadCallback(const char* className)
626{
627 return ((TCling*)gCling)->AutoLoad(className);
628}
629
630extern "C" int TCling__AutoParseCallback(const char* className)
631{
632 return ((TCling*)gCling)->AutoParse(className);
633}
634
635extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
636{
637 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
638}
639
640// Returns 0 for failure 1 for success
641extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
642{
643 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
644}
645
646extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
647{
648 string file(fileName);
649 string opt(options);
650 return gSystem->CompileMacro(file.c_str(), opt.c_str());
651}
652
653extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
654 string &args, string &io, string &fname)
655{
656 string file(fileName);
657 TString f, amode, arguments, aclicio;
658 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
659 mode = amode.Data(); args = arguments.Data();
660 io = aclicio.Data(); fname = f.Data();
661}
662
663//______________________________________________________________________________
664//
665//
666//
667
668#ifdef R__WIN32
669extern "C" {
670 char *__unDName(char *demangled, const char *mangled, int out_len,
671 void * (* pAlloc )(size_t), void (* pFree )(void *),
672 unsigned short int flags);
673}
674#endif
675
676////////////////////////////////////////////////////////////////////////////////
677/// Find a template decl within N nested namespaces, 0<=N<inf
678/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
679/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
680/// Returns nullptr in case of error
681
682static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
683{
684 using namespace clang;
685 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
686 return FindTemplateInNamespace(*nsd->decls_begin());
687 }
688
689 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
690 return ctd;
691 }
692
693 return nullptr; // something went wrong.
694}
695
696//______________________________________________________________________________
697//
698//
699//
700
701int TCling_GenerateDictionary(const std::vector<std::string> &classes,
702 const std::vector<std::string> &headers,
703 const std::vector<std::string> &fwdDecls,
704 const std::vector<std::string> &unknown)
705{
706 //This function automatically creates the "LinkDef.h" file for templated
707 //classes then executes CompileMacro on it.
708 //The name of the file depends on the class name, and it's not generated again
709 //if the file exist.
710 if (classes.empty()) {
711 return 0;
712 }
713 // Use the name of the first class as the main name.
714 const std::string& className = classes[0];
715 //(0) prepare file name
716 TString fileName = "AutoDict_";
717 std::string::const_iterator sIt;
718 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
719 if (*sIt == '<' || *sIt == '>' ||
720 *sIt == ' ' || *sIt == '*' ||
721 *sIt == ',' || *sIt == '&' ||
722 *sIt == ':') {
723 fileName += '_';
724 }
725 else {
726 fileName += *sIt;
727 }
728 }
729 if (classes.size() > 1) {
730 Int_t chk = 0;
731 std::vector<std::string>::const_iterator it = classes.begin();
732 while ((++it) != classes.end()) {
733 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
734 chk = chk * 3 + it->at(cursor);
735 }
736 }
737 fileName += TString::Format("_%u", chk);
738 }
739 fileName += ".cxx";
740 if (gSystem->AccessPathName(fileName) != 0) {
741 //file does not exist
742 //(1) prepare file data
743 // If STL, also request iterators' operators.
744 // vector is special: we need to check whether
745 // vector::iterator is a typedef to pointer or a
746 // class.
747 static const std::set<std::string> sSTLTypes {
748 "vector","list","forward_list","deque","map","unordered_map","multimap",
749 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
750 "queue","priority_queue","stack","iterator"};
751 std::vector<std::string>::const_iterator it;
752 std::string fileContent("");
753 for (it = headers.begin(); it != headers.end(); ++it) {
754 fileContent += "#include \"" + *it + "\"\n";
755 }
756 for (it = unknown.begin(); it != unknown.end(); ++it) {
757 TClass* cl = TClass::GetClass(it->c_str());
758 if (cl && cl->GetDeclFileName()) {
759 TString header = gSystem->BaseName(cl->GetDeclFileName());
762 while (dirbase.Length() && dirbase != "."
763 && dirbase != "include" && dirbase != "inc"
764 && dirbase != "prec_stl") {
766 dir = gSystem->GetDirName(dir);
767 }
768 fileContent += TString("#include \"") + header + "\"\n";
769 }
770 }
771 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
772 fileContent += "class " + *it + ";\n";
773 }
774 fileContent += "#ifdef __CLING__ \n";
775 fileContent += "#pragma link C++ nestedclasses;\n";
776 fileContent += "#pragma link C++ nestedtypedefs;\n";
777 for (it = classes.begin(); it != classes.end(); ++it) {
778 std::string n(*it);
779 size_t posTemplate = n.find('<');
780 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
781 if (posTemplate != std::string::npos) {
782 n.erase(posTemplate, std::string::npos);
783 if (n.compare(0, 5, "std::") == 0) {
784 n.erase(0, 5);
785 }
786 iSTLType = sSTLTypes.find(n);
787 }
788 fileContent += "#pragma link C++ class ";
789 fileContent += *it + "+;\n" ;
790 if (iSTLType == sSTLTypes.end()) {
791 // Not an STL class; we need to allow the I/O of contained
792 // classes (now that we have a dictionary for them).
793 fileContent += "#pragma link C++ class " + *it + "::*+;\n" ;
794 }
795 }
796 fileContent += "#endif\n";
797 //end(1)
798 //(2) prepare the file
800 filePointer = fopen(fileName, "w");
801 if (filePointer == nullptr) {
802 //can't open a file
803 return 1;
804 }
805 //end(2)
806 //write data into the file
807 fprintf(filePointer, "%s", fileContent.c_str());
809 }
810 //(3) checking if we can compile a macro, if not then cleaning
812 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
813 Int_t ret = gSystem->CompileMacro(fileName, "k");
815 if (ret == 0) { //can't compile a macro
816 return 2;
817 }
818 //end(3)
819 return 0;
820}
821
822int TCling_GenerateDictionary(const std::string& className,
823 const std::vector<std::string> &headers,
824 const std::vector<std::string> &fwdDecls,
825 const std::vector<std::string> &unknown)
826{
827 //This function automatically creates the "LinkDef.h" file for templated
828 //classes then executes CompileMacro on it.
829 //The name of the file depends on the class name, and it's not generated again
830 //if the file exist.
831 std::vector<std::string> classes;
832 classes.push_back(className);
834}
835
836//______________________________________________________________________________
837//
838//
839//
840
841// It is a "fantom" method to synchronize user keyboard input
842// and ROOT prompt line (for WIN32)
843const char* fantomline = "TRint::EndOfLineAction();";
844
845//______________________________________________________________________________
846//
847//
848//
849
850void* TCling::fgSetOfSpecials = nullptr;
851
852//______________________________________________________________________________
853//
854// llvm error handler through exceptions; see also cling/UserInterface
855//
856namespace {
857 // Handle fatal llvm errors by throwing an exception.
858 // Yes, throwing exceptions in error handlers is bad.
859 // Doing nothing is pretty terrible, too.
860 void exceptionErrorHandler(void * /*user_data*/,
861 const char *reason,
862 bool /*gen_crash_diag*/) {
863 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
864 }
865}
866
867//______________________________________________________________________________
868//
869//
870//
871
872////////////////////////////////////////////////////////////////////////////////
873
874namespace{
875 // An instance of this class causes the diagnostics of clang to be suppressed
876 // during its lifetime
877 class clangDiagSuppr {
878 public:
879 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
880 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
881 fDiagEngine.setIgnoreAllWarnings(true);
882 }
883
885 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
886 }
887 private:
888 clang::DiagnosticsEngine& fDiagEngine;
889 bool fOldDiagValue;
890 };
891
892}
893
894////////////////////////////////////////////////////////////////////////////////
895/// Allow calling autoparsing from TMetaUtils
897{
898 return gCling->AutoParse(cname);
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Try hard to avoid looking up in the Cling database as this could enduce
903/// an unwanted autoparsing.
904
906 std::string &result)
907{
908 result.clear();
909
910 unsigned long offset = 0;
911 if (strncmp(tname.c_str(), "const ", 6) == 0) {
912 offset = 6;
913 }
914 unsigned long end = tname.length();
915 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
916 if ( tname[end-1]==']' ) {
917 --end;
918 while ( end && tname[end-1]!='[' ) --end;
919 }
920 --end;
921 }
922 std::string innerbuf;
923 const char *inner;
924 if (end != tname.length()) {
925 innerbuf = tname.substr(offset,end-offset);
926 inner = innerbuf.c_str();
927 } else {
928 inner = tname.c_str()+offset;
929 }
930
931 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
932 if (gROOT->GetListOfClasses()->FindObject(inner)
934 // This is a known class.
935 return true;
936 }
937
938 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
939 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
940 if (type) {
941 // This is a raw type and an already loaded typedef.
942 const char *newname = type->GetFullTypeName();
943 if (type->GetType() == kLong64_t) {
944 newname = "Long64_t";
945 } else if (type->GetType() == kULong64_t) {
946 newname = "ULong64_t";
947 }
948 if (strcmp(inner,newname) == 0) {
949 return true;
950 }
951 if (offset) result = "const ";
952 result += newname;
953 if ( end != tname.length() ) {
954 result += tname.substr(end,tname.length()-end);
955 }
956 if (result == tname) result.clear();
957 return true;
958 }
959
960 // Check if the name is an enumerator
962 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
963 {
964 // We have a scope
965 const auto enName = lastPos;
966 const auto scopeNameSize = (lastPos - inner) / sizeof(decltype(*lastPos)) - 2;
967 std::string scopeName{inner, scopeNameSize};
968 // Check if the scope is in the list of classes
969 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName.c_str()))) {
970 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
971 if (enumTable && enumTable->THashList::FindObject(enName))
972 return true;
973 }
974 // It may still be in one of the loaded protoclasses
975 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName.c_str()))) {
976 auto listOfEnums = scope->GetListOfEnums();
977 if (listOfEnums) { // it could be null: no enumerators in the protoclass
978 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
979 if (enumTable && enumTable->THashList::FindObject(enName))
980 return true;
981 }
982 }
983 } else
984 {
985 // We don't have any scope: this could only be a global enum
986 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
987 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
988 }
989
991 {
992 // This is a class name.
993 return true;
994 }
995
996 return false;
997}
998
999////////////////////////////////////////////////////////////////////////////////
1000/// Check if the class name is present in TClassTable.
1001///
1002/// \param[in] tname class name to check.
1003/// \param[out] result If a class name has an alternative name registered in
1004/// TClassTable, it will be copied into this string.
1005bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
1006{
1007 result.clear();
1008
1009 if (gROOT->GetListOfClasses()->FindObject(tname.c_str()) || TClassTable::Check(tname.c_str(), result)) {
1010 // This is a known class.
1011 return true;
1012 }
1013
1014 return false;
1015}
1016
1017////////////////////////////////////////////////////////////////////////////////
1018
1023
1024////////////////////////////////////////////////////////////////////////////////
1025
1027{
1028 return fContent.c_str();
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Append string to the storage if not added already.
1033
1034inline bool TCling::TUniqueString::Append(const std::string& str)
1035{
1036 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1037 if (notPresent){
1038 fContent+=str;
1039 }
1040 return notPresent;
1041}
1042
1043std::string TCling::ToString(const char* type, void* obj)
1044{
1045 return fInterpreter->toString(type, obj);
1046}
1047
1048////////////////////////////////////////////////////////////////////////////////
1049///\returns true if the module was loaded.
1050static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1051{
1052 // When starting up ROOT, cling would load all modulemap files on the include
1053 // paths. However, in a ROOT session, it is very common to run aclic which
1054 // will invoke rootcling and possibly produce a modulemap and a module in
1055 // the current folder.
1056 //
1057 // Before failing, try loading the modulemap in the current folder and try
1058 // loading the requested module from it.
1059 std::string currentDir = gSystem->WorkingDirectory();
1060 assert(!currentDir.empty());
1062 if (gDebug > 2)
1063 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1064 ModuleName.c_str());
1065
1066 return interp.loadModule(ModuleName, /*Complain=*/true);
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Loads the C++ modules that we require to run any ROOT program. This is just
1071/// supposed to make a C++ module from a modulemap available to the interpreter.
1072static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1073{
1074 for (const auto &modName : modules)
1076}
1077
1078static bool IsFromRootCling() {
1079 // rootcling also uses TCling for generating the dictionary ROOT files.
1080 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1081 return foundSymbol;
1082}
1083
1084/// Checks if there is an ASTFile on disk for the given module \c M.
1085static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1086{
1087 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1088
1089 std::string ModuleFileName;
1090 if (!HSOpts.PrebuiltModulePaths.empty())
1091 // Load the module from *only* in the prebuilt module path.
1092 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1093 if (FullFileName)
1095
1096 return !ModuleFileName.empty();
1097}
1098
1099static bool HaveFullGlobalModuleIndex = false;
1101{
1102 CompilerInstance &CI = *interp.getCI();
1103 Preprocessor &PP = CI.getPreprocessor();
1104 auto ModuleManager = CI.getASTReader();
1106 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1107 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1108 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1109 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1110 if (ModuleIndexPath.empty())
1111 return nullptr;
1112 // Get an existing global index. This loads it if not already loaded.
1113 ModuleManager->resetForReload();
1114 ModuleManager->loadGlobalIndex();
1115 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1116
1117 // For finding modules needing to be imported for fixit messages,
1118 // we need to make the global index cover all modules, so we do that here.
1120 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1121 bool RecreateIndex = false;
1122 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1123 Module *TheModule = I->second;
1124 // We want the index only of the prebuilt modules.
1126 continue;
1127 LoadModule(TheModule->Name, interp);
1128 RecreateIndex = true;
1129 }
1130 if (RecreateIndex) {
1131 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1132 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1133
1134 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1135 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1136 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1138 }
1139 bool VisitNamedDecl(NamedDecl *ND) {
1140 if (!ND->isFromASTFile())
1141 return true;
1142 if (!ND->getIdentifier())
1143 return true;
1144
1145 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1146 return true;
1147
1148 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1149 if (TD->isCompleteDefinition())
1150 Register(TD);
1151 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1152 Register(NSD, /*AddSingleEntry=*/ false);
1153 }
1155 Register(TND);
1156 // FIXME: Add the rest...
1157 return true; // continue decending
1158 }
1159 private:
1160 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1161 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1162 assert(ND->isFromASTFile());
1163 // FIXME: All decls should have an owning module once rootcling
1164 // updates its generated decls from within the LookupHelper & co.
1165 if (!ND->hasOwningModule()) {
1166#ifndef NDEBUG
1167 SourceManager &SM = ND->getASTContext().getSourceManager();
1168 SourceLocation Loc = ND->getLocation();
1169 OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
1170 (void)FE;
1171 assert(FE->getName().contains("input_line_"));
1172#endif
1173 return;
1174 }
1175
1176 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1178 assert(!ND->getName().empty() && "Empty name");
1179 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1180 return;
1181 // FIXME: The FileEntry in not stable to serialize.
1182 // FIXME: We might end up with many times with the same module.
1183 // FIXME: We might end up two modules containing a definition.
1184 // FIXME: What do we do if no definition is found.
1185 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1186 }
1187 };
1188 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1189
1190 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1191 CI.getPCHContainerReader(),
1193 &IDs));
1194 ModuleManager->resetForReload();
1195 ModuleManager->loadGlobalIndex();
1196 GlobalIndex = ModuleManager->getGlobalIndex();
1197 }
1199 }
1200 return GlobalIndex;
1201}
1202
1203static void RegisterCxxModules(cling::Interpreter &clingInterp)
1204{
1205 if (!clingInterp.getCI()->getLangOpts().Modules)
1206 return;
1207
1208 // Loading of a module might deserialize.
1209 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1210
1211 // Setup core C++ modules if we have any to setup.
1212
1213 // Load libc and stl first.
1214 // Load vcruntime module for windows
1215#ifdef R__WIN32
1216 LoadModule("vcruntime", clingInterp);
1217 LoadModule("services", clingInterp);
1218#endif
1219
1220#ifdef R__MACOSX
1221 LoadModule("Darwin", clingInterp);
1222#else
1223 LoadModule("libc", clingInterp);
1224#endif
1225 LoadModule("std", clingInterp);
1226
1227 LoadModule("_Builtin_intrinsics", clingInterp);
1228
1229 // Load core modules
1230 // This should be vector in order to be able to pass it to LoadModules
1231 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1232 "ROOT_Config",
1233 "ROOT_Rtypes",
1234 "ROOT_Foundation_Stage1_NoRTTI",
1235 "Core",
1236 "Rint",
1237 "RIO"};
1238
1240
1241 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1242 if (!IsFromRootCling()) {
1243 std::vector<std::string> CommonModules = {"MathCore"};
1245
1246 // These modules should not be preloaded but they fix issues.
1247 // FIXME: Hist is not a core module but is very entangled to MathCore and
1248 // causes issues.
1249 std::vector<std::string> FIXMEModules = {"Hist"};
1250 clang::CompilerInstance &CI = *clingInterp.getCI();
1251 clang::Preprocessor &PP = CI.getPreprocessor();
1252 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1253 if (MMap.findModule("RInterface"))
1254 FIXMEModules.push_back("RInterface");
1255
1257
1258 GlobalModuleIndex *GlobalIndex = nullptr;
1260 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1261 // We should investigate how to suppress it completely.
1262 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1263
1264 llvm::StringSet<> KnownModuleFileNames;
1265 if (GlobalIndex)
1266 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1267
1268 std::vector<std::string> PendingModules;
1269 PendingModules.reserve(256);
1270 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1271 clang::Module *M = I->second;
1272 assert(M);
1273
1274 // We want to load only already created modules.
1275 std::string FullASTFilePath;
1277 continue;
1278
1280 continue;
1281
1282 if (M->IsUnimportable)
1283 continue;
1284
1285 if (GlobalIndex)
1286 LoadModule(M->Name, clingInterp);
1287 else {
1288 // FIXME: We may be able to remove those checks as cling::loadModule
1289 // checks if a module was alredy loaded.
1290 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1291 continue; // This is a core module which was already loaded.
1292
1293 // Load system modules now and delay the other modules after we have
1294 // loaded all system ones.
1295 if (M->IsSystem)
1296 LoadModule(M->Name, clingInterp);
1297 else
1298 PendingModules.push_back(M->Name);
1299 }
1300 }
1302 }
1303
1304 // Check that the gROOT macro was exported by any core module.
1305 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1306
1307 // `ERROR` and `PI` are from loading R related modules, which conflict with
1308 // user's code.
1309 clingInterp.declare(R"CODE(
1310#ifdef PI
1311# undef PI
1312#endif
1313#ifdef ERROR
1314# undef ERROR
1315#endif
1316 )CODE");
1317}
1318
1319static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1320{
1321 std::string PreIncludes;
1322 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1323
1324 // For the list to also include string, we have to include it now.
1325 // rootcling does parts already if needed, e.g. genreflex does not want using
1326 // namespace std.
1327 if (IsFromRootCling()) {
1328 PreIncludes += "#include \"RtypesCore.h\"\n";
1329 } else {
1330 if (!hasCxxModules)
1331 PreIncludes += "#include \"Rtypes.h\"\n";
1332
1334 + gInterpreterClassDef + "\n"
1335 "#undef ClassImp\n"
1336 "#define ClassImp(X);\n";
1337 }
1338 if (!hasCxxModules)
1339 PreIncludes += "#include <string>\n";
1340
1341 // We must include it even when we have modules because it is marked as
1342 // textual in the modulemap due to the nature of the assert header.
1343#ifndef R__WIN32
1344 PreIncludes += "#include <cassert>\n";
1345#endif
1346 PreIncludes += "using namespace std;\n";
1347 clingInterp.declare(PreIncludes);
1348}
1349
1350////////////////////////////////////////////////////////////////////////////////
1351/// Initialize the cling interpreter interface.
1352/// \param name name for TInterpreter
1353/// \param title title for TInterpreter
1354/// \param argv - array of arguments passed to the cling::Interpreter constructor
1355/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1356/// \param interpLibHandle handle to interpreter library
1357
1358TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1359: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1360 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr), fLookupHelper(nullptr),
1361 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1363{
1364 fPrompt[0] = 0;
1365 const bool fromRootCling = IsFromRootCling();
1366
1367 fCxxModulesEnabled = false;
1368#ifdef R__USE_CXXMODULES
1369 fCxxModulesEnabled = true;
1370#endif
1371
1372 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1373
1374 fTemporaries = new std::vector<cling::Value>();
1375
1376 std::vector<std::string> clingArgsStorage;
1377 clingArgsStorage.push_back("cling4root");
1378 for (const char* const* arg = argv; *arg; ++arg)
1379 clingArgsStorage.push_back(*arg);
1380
1381 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1382 if (!fromRootCling) {
1384
1385 // Add -I early so ASTReader can find the headers.
1386 std::string interpInclude(TROOT::GetEtcDir().Data());
1387 clingArgsStorage.push_back("-I" + interpInclude);
1388
1389 // Add include path to etc/cling.
1390 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1391
1392 // Add include path to etc/cling.
1393 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1394
1395 // Add the root include directory and etc/ to list searched by default.
1396 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1397
1398 // Add the current path to the include path
1399 // TCling::AddIncludePath(".");
1400
1401 // Attach the PCH (unless we have C++ modules enabled which provide the
1402 // same functionality).
1403 if (!fCxxModulesEnabled) {
1404 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1405 if (gSystem->Getenv("ROOT_PCH")) {
1406 pchFilename = gSystem->Getenv("ROOT_PCH");
1407 }
1408
1409 clingArgsStorage.push_back("-include-pch");
1410 clingArgsStorage.push_back(pchFilename);
1411 }
1412
1413 clingArgsStorage.push_back("-Wno-undefined-inline");
1414 clingArgsStorage.push_back("-fsigned-char");
1415 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1416 // See the GitHub issues #9809 and #9944
1417 // TODO: to be reviewed after the upgrade of LLVM & Clang
1418#ifndef _MSC_VER
1419 clingArgsStorage.push_back("-O1");
1420 // Disable optimized register allocation which is turned on automatically
1421 // by -O1, but seems to require -O2 to not explode in run time.
1422 clingArgsStorage.push_back("-mllvm");
1423 clingArgsStorage.push_back("-optimize-regalloc=0");
1424#endif
1425 }
1426
1427 // Process externally passed arguments if present.
1428 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1429 if (EnvOpt.has_value()) {
1431 while (!Env.empty()) {
1432 StringRef Arg;
1433 std::tie(Arg, Env) = Env.split(' ');
1434 clingArgsStorage.push_back(Arg.str());
1435 }
1436 }
1437
1438 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1439 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1440 if (EnvOpt.has_value()) {
1442 while (!Env.empty()) {
1443 StringRef Arg;
1444 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1445 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1446 Paths.push_back(Arg.str());
1447 }
1448 }
1449 };
1450
1451 if (fCxxModulesEnabled) {
1452 std::vector<std::string> Paths;
1453 // ROOT usually knows better where its libraries are. This way we can
1454 // discover modules without having to should thisroot.sh and should fix
1455 // gnuinstall.
1456 Paths.push_back(TROOT::GetSharedLibDir().Data());
1457 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1458 std::string EnvVarPath;
1459 for (const std::string& P : Paths)
1461 // FIXME: We should make cling -fprebuilt-module-path work.
1462 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1463 }
1464
1465 // FIXME: This only will enable frontend timing reports.
1466 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1467 if (EnvOpt.has_value())
1468 clingArgsStorage.push_back("-ftime-report");
1469
1470 // Add the overlay file. Note that we cannot factor it out for both root
1471 // and rootcling because rootcling activates modules only if -cxxmodule
1472 // flag is passed.
1474 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1475 std::vector<std::string> ModuleMaps;
1476 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1477 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1478 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1479
1480 std::string cwd = gSystem->WorkingDirectory();
1481 // Give highest precedence of the modulemap in the cwd if any.
1482 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1483 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1484
1485 for (const std::string& M : ModuleMaps)
1486 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1487
1488 std::string ModulesCachePath;
1489 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1490 if (EnvOpt.has_value()){
1492 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1493 ModulesCachePath = Env.str();
1494 } else {
1496 }
1497
1498 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1499 }
1500
1501 std::vector<const char*> interpArgs;
1502 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1504 interpArgs.push_back(iArg->c_str());
1505
1506 // Activate C++ modules support. If we are running within rootcling, it's up
1507 // to rootcling to set this flag depending on whether it wants to produce
1508 // C++ modules.
1510 if (fCxxModulesEnabled) {
1511 if (!fromRootCling) {
1512 // We only set this flag, rest is done by the CIFactory.
1513 interpArgs.push_back("-fmodules");
1514 interpArgs.push_back("-fno-implicit-module-maps");
1515 // We should never build modules during runtime, so let's enable the
1516 // module build remarks from clang to make it easier to spot when we do
1517 // this by accident.
1518 interpArgs.push_back("-Rmodule-build");
1519 }
1520 // ROOT implements its AutoLoading upon module's link directives. We
1521 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1522 // facilities use the link directive to dynamically load the relevant
1523 // library. So, we need to suppress clang's default autolink behavior.
1524 interpArgs.push_back("-fno-autolink");
1525 }
1526
1527#ifdef R__FAST_MATH
1528 // Same setting as in rootcling_impl.cxx.
1529 interpArgs.push_back("-ffast-math");
1530#endif
1531
1533 // Add statically injected extra arguments, usually coming from rootcling.
1534 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1535 extraArgs && *extraArgs; ++extraArgs) {
1536 if (!strcmp(*extraArgs, "-resource-dir")) {
1537 // Take the next arg as the llvm resource directory.
1539 } else {
1540 interpArgs.push_back(*extraArgs);
1541 }
1542 }
1543
1544 std::vector<std::string> _empty;
1546 for (const auto &arg: args)
1547 interpArgs.emplace_back(arg.c_str());
1548
1549 // Add the Rdict module file extension.
1550 cling::Interpreter::ModuleFileExtensions extensions;
1551 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1552 if (!EnvOpt.has_value())
1553 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1554
1555 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1556 &(interpArgs[0]),
1559
1560 if (!fInterpreter->getCI()) { // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1561 return;
1562 }
1563
1564 // Tell CppInterOp that the cling::Interpreter instance is managed externally by ROOT
1565 // Sets the interpreter by passing the fInterpreter handle as soon as TCling is initialized
1566 Cpp::UseExternalInterpreter((Cpp::TInterp_t*)fInterpreter.get());
1567
1568 // Don't check whether modules' files exist.
1569 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1570 DisableValidationForModuleKind::All;
1571
1572 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1573 // to disable spell checking.
1574 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1575
1576 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1577 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1578 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1579 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1580
1581 // We need stream that doesn't close its file descriptor, thus we are not
1582 // using llvm::outs. Keeping file descriptor open we will be able to use
1583 // the results in pipes (Savannah #99234).
1584 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1585 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1586
1589
1590 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1596
1597 // Disallow auto-parsing in rootcling
1599
1600 ResetAll();
1601
1602 // Enable dynamic lookup
1603 if (!fromRootCling) {
1604 fInterpreter->enableDynamicLookup();
1605 }
1606
1607 // Enable ClinG's DefinitionShadower for ROOT.
1608 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1609 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1610 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1611 // FIXME: We should probably switch to the default printing policy setting
1612 // after adjusting tons of reference files.
1613 Policy.SplitTemplateClosers = true;
1614 // Keep default templare arguments, required for dictionary generation.
1615 Policy.SuppressDefaultTemplateArgs = false;
1616
1617
1618 // Attach cling callbacks last; they might need TROOT::fInterpreter
1619 // and should thus not be triggered during the equivalent of
1620 // TROOT::fInterpreter = new TCling;
1621 std::unique_ptr<TClingCallbacks>
1625 fInterpreter->setCallbacks(std::move(clingCallbacks));
1626
1627 if (!fromRootCling) {
1628 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1629 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1630 // e.g. because of an RPATH build.
1631 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1632 /*prepend=*/true);
1633 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1634 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1635 return stem.starts_with("libNew") || stem.starts_with("libcppyy_backend");
1636 };
1637 // Initialize the dyld for AutoloadLibraryGenerator.
1638 DLM.initializeDyld(ShouldPermanentlyIgnore);
1639 }
1640}
1641
1642
1643////////////////////////////////////////////////////////////////////////////////
1644/// Destroy the interpreter interface.
1645
1647{
1648 // ROOT's atexit functions require the interepreter to be available.
1649 // Run them before shutting down.
1650 if (!IsFromRootCling())
1651 GetInterpreterImpl()->runAtExitFuncs();
1652 fIsShuttingDown = true;
1653 delete fMapfile;
1654 delete fRootmapFiles;
1655 delete fTemporaries;
1656 delete fNormalizedCtxt;
1657 delete fLookupHelper;
1658 gCling = nullptr;
1659}
1660
1661////////////////////////////////////////////////////////////////////////////////
1662/// Initialize the interpreter, once TROOT::fInterpreter is set.
1663
1665{
1666 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1667 return;
1669
1670 // We are set up. Enable ROOT's AutoLoading.
1671 if (IsFromRootCling())
1672 return;
1673
1674 // Read the rules before enabling the auto loading to not inadvertently
1675 // load the libraries for the classes concerned even-though the user is
1676 // *not* using them.
1677 // Note this call must happen before the first call to LoadLibraryMap.
1678 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1679 TClass::ReadRules(); // Read the default customization rules ...
1680
1682 SetClassAutoLoading(true);
1683}
1684
1686{
1687 fIsShuttingDown = true;
1688 ResetGlobals();
1689}
1690
1691////////////////////////////////////////////////////////////////////////////////
1692/// Helper to initialize TVirtualStreamerInfo's factor early.
1693/// Use static initialization to insure only one TStreamerInfo is created.
1695{
1696 // Use lambda since SetFactory return void.
1697 auto setFactory = []() {
1699 return kTRUE;
1700 };
1701 static bool doneFactory = setFactory();
1702 return doneFactory; // avoid unused variable warning.
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Register Rdict data for future loading by LoadPCM;
1707
1708void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1709{
1710 if (IsFromRootCling())
1711 return;
1712
1713 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1714 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1715 return;
1716 }
1717
1718 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1719 // a link to a non-existent file.
1721}
1722
1723////////////////////////////////////////////////////////////////////////////////
1724/// Tries to load a PCM from TFile; returns true on success.
1725/// The caller of this function should be holding the ROOT Write lock.
1726
1728{
1729 auto listOfKeys = pcmFile.GetListOfKeys();
1730
1731 // This is an empty pcm
1732 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1733 ((listOfKeys->GetSize() == 1) && // only one, and
1734 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1735 ))) {
1736 return;
1737 }
1738
1740 if (gDebug > 1)
1741 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1742
1744 pcmFile.GetObject("__Enums", enums);
1745 if (enums) {
1746 // Cache the pointers
1747 auto listOfGlobals = gROOT->GetListOfGlobals();
1748 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1749 // Loop on enums and then on enum constants
1750 for (auto selEnum : *enums) {
1751 const char *enumScope = selEnum->GetTitle();
1752 const char *enumName = selEnum->GetName();
1753 if (strcmp(enumScope, "") == 0) {
1754 // This is a global enum and is added to the
1755 // list of enums and its constants to the list of globals
1756 if (!listOfEnums->THashList::FindObject(enumName)) {
1757 ((TEnum *)selEnum)->SetClass(nullptr);
1758 listOfEnums->Add(selEnum);
1759 }
1760 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1761 if (!listOfGlobals->FindObject(enumConstant)) {
1763 }
1764 }
1765 } else {
1766 // This enum is in a namespace. A TClass entry is bootstrapped if
1767 // none exists yet and the enum is added to it
1769 if (!nsTClassEntry) {
1771 }
1772 auto listOfEnums = nsTClassEntry->fEnums.load();
1773 if (!listOfEnums) {
1774 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1775 // For this case, the list will be immutable once constructed
1776 // (i.e. in this case, by the end of this routine).
1778 } else {
1779 // namespaces can have enums added to them
1781 }
1782 }
1783 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1784 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1785 listOfEnums->Add(selEnum);
1786 }
1787 }
1788 }
1789 enums->Clear();
1790 delete enums;
1791 }
1792
1793 pcmFile.GetObject("__ProtoClasses", protoClasses);
1794
1795 if (protoClasses) {
1796 for (auto obj : *protoClasses) {
1797 TProtoClass *proto = (TProtoClass *)obj;
1799 }
1800 // Now that all TClass-es know how to set them up we can update
1801 // existing TClasses, which might cause the creation of e.g. TBaseClass
1802 // objects which in turn requires the creation of TClasses, that could
1803 // come from the PCH, but maybe later in the loop. Instead of resolving
1804 // a dependency graph the addition to the TClassTable above allows us
1805 // to create these dependent TClasses as needed below.
1806 for (auto proto : *protoClasses) {
1807 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1808 // We have an existing TClass object. It might be emulated
1809 // or interpreted; we now have more information available.
1810 // Make that available.
1811 if (existingCl->GetState() != TClass::kHasTClassInit) {
1812 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1813 if (!dict) {
1814 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1815 } else {
1816 // This will replace the existing TClass.
1817 TClass *ncl = (*dict)();
1818 if (ncl)
1819 ncl->PostLoadCheck();
1820 }
1821 }
1822 }
1823 }
1824
1825 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1826 delete protoClasses;
1827 }
1828
1830 pcmFile.GetObject("__Typedefs", dataTypes);
1831 if (dataTypes) {
1832 for (auto typedf : *dataTypes)
1833 gROOT->GetListOfTypes()->Add(typedf);
1834 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1835 delete dataTypes;
1836 }
1837}
1838
1839////////////////////////////////////////////////////////////////////////////////
1840/// Tries to load a rdict PCM, issues diagnostics if it fails.
1841/// The caller of this function should be holding the ROOT Write lock.
1842
1844{
1847 assert(!pcmFileNameFullPath.empty());
1848 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1849
1850 // Easier to work with the ROOT interfaces.
1852
1853 // Prevent the ROOT-PCMs hitting this during auto-load during
1854 // JITting - which will cause recursive compilation.
1855 // Avoid to call the plugin manager at all.
1857
1859 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1860 if (gDebug > 5) {
1861 gDebug -= 5;
1862 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1863 } else {
1864 gDebug = 0;
1865 }
1866
1867 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1869
1871 if (pendingRdict != fPendingRdicts.end()) {
1872 llvm::StringRef pcmContent = pendingRdict->second;
1874 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1876
1877 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1879 // Currently the module file are never unloaded (even if the library is
1880 // unloaded) and, of course, never reloaded.
1881 // Consequently, we must NOT remove the `pendingRdict` from the list
1882 // of pending dictionary, otherwise if a library is unloaded and then
1883 // reload we will be unable to update properly the TClass object
1884 // (because we wont be able to load the rootpcm file by executing the
1885 // above lines)
1886
1887 return;
1888 }
1889
1890 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1891 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1892 pcmFileNameFullPath.data());
1893 if (!fPendingRdicts.empty())
1894 for (const auto &rdict : fPendingRdicts)
1895 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1896 rdict.first.c_str());
1897 return;
1898 }
1899
1900 if (!gROOT->IsRootFile(pcmFileName)) {
1901 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1902 return;
1903 }
1904 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1906}
1907
1908//______________________________________________________________________________
1909
1910namespace {
1911 using namespace clang;
1912
1913 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1914 // This class is to be considered an helper for autoparsing.
1915 // It visits the AST and marks all classes (in all of their redeclarations)
1916 // with the setHasExternalLexicalStorage method.
1917 public:
1918 bool VisitRecordDecl(clang::RecordDecl* rcd){
1919 if (gDebug > 2)
1920 Info("ExtLexicalStorageAdder",
1921 "Adding external lexical storage to class %s",
1922 rcd->getNameAsString().c_str());
1923 auto reDeclPtr = rcd->getMostRecentDecl();
1924 do {
1925 reDeclPtr->setHasExternalLexicalStorage();
1926 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1927
1928 return false;
1929 }
1930 };
1931
1932
1933}
1934
1935////////////////////////////////////////////////////////////////////////////////
1936///\returns true if the module map was loaded, false on error or if the map was
1937/// already loaded.
1939 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1940{
1941 assert(llvm::sys::path::is_absolute(FullPath));
1942 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1943 FileManager &FM = PP.getFileManager();
1944 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1945 // We should look for modulemap files there too.
1946 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1947 HeaderSearch &HS = PP.getHeaderSearchInfo();
1948 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1949 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1950 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1951 if (!pathExists)
1952 HSOpts.AddPrebuiltModulePath(FullPath);
1953 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1954 // because its internal call to getFile has CacheFailure set to true.
1955 // In our case, modulemaps can appear any time due to ACLiC.
1956 // Code copied from HS.lookupModuleMapFile.
1957 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1958 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1959 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1960 /*CacheFailure*/ false)) {
1961 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1962 return true;
1963 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1964 }
1965 }
1966 return false;
1967}
1968
1969////////////////////////////////////////////////////////////////////////////////
1970/// List of dicts that have the PCM information already in the PCH.
1971static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1972 "libRint",
1973 "libThread",
1974 "libRIO",
1975 "libImt",
1976 "libMultiProc",
1977 "libcomplexDict",
1978 "libdequeDict",
1979 "liblistDict",
1980 "libforward_listDict",
1981 "libvectorDict",
1982 "libmapDict",
1983 "libmultimap2Dict",
1984 "libmap2Dict",
1985 "libmultimapDict",
1986 "libsetDict",
1987 "libmultisetDict",
1988 "libunordered_setDict",
1989 "libunordered_multisetDict",
1990 "libunordered_mapDict",
1991 "libunordered_multimapDict",
1992 "libvalarrayDict",
1993 "G__GenVector32",
1994 "G__Smatrix32"};
1995
1996static void PrintDlError(const char *dyLibName, const char *modulename)
1997{
1998#ifdef R__WIN32
1999 char dyLibError[1000];
2001 dyLibError, sizeof(dyLibError), NULL);
2002#else
2003 const char *dyLibError = dlerror();
2004#endif
2005 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2006 (dyLibError) ? dyLibError : "");
2007}
2008
2009////////////////////////////////////////////////////////////////////////////////
2010// Update all the TClass registered in fClassesToUpdate
2011
2013{
2014 while (!fClassesToUpdate.empty()) {
2015 TClass *oldcl = fClassesToUpdate.back().first;
2016 // If somehow the TClass has already been loaded (maybe it was registered several time),
2017 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2018 // maybe even kForwardDeclared and needs to replaced.
2019 if (oldcl->GetState() != TClass::kHasTClassInit) {
2020 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2021 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2022 fClassesToUpdate.pop_back();
2023 // Calling func could manipulate the list so, let maintain the list
2024 // then call the dictionary function.
2025 TClass *ncl = dict();
2026 if (ncl) ncl->PostLoadCheck();
2027 } else {
2028 fClassesToUpdate.pop_back();
2029 }
2030 }
2031}
2032////////////////////////////////////////////////////////////////////////////////
2033/// Inject the module named "modulename" into cling; load all headers.
2034/// headers is a 0-terminated array of header files to `#include` after
2035/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2036/// entries (or %PATH% on Windows).
2037/// This function gets called by the static initialization of dictionary
2038/// libraries.
2039/// The payload code is injected "as is" in the interpreter.
2040/// The value of 'triggerFunc' is used to find the shared library location.
2041/// The caller of this function should be holding the ROOT Write lock.
2042
2044 const char** headers,
2045 const char** includePaths,
2046 const char* payloadCode,
2047 const char* fwdDeclsCode,
2048 void (*triggerFunc)(),
2050 const char** classesHeaders,
2051 Bool_t lateRegistration /*=false*/,
2052 Bool_t hasCxxModule /*=false*/)
2053{
2054 const bool fromRootCling = IsFromRootCling();
2055 // We need the dictionary initialization but we don't want to inject the
2056 // declarations into the interpreter, except for those we really need for
2057 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2058 if (fromRootCling) return;
2059
2060 // When we cannot provide a module for the library we should enable header
2061 // parsing. This 'mixed' mode ensures gradual migration to modules.
2062 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2064
2065 // Treat Aclic Libs in a special way. Do not delay the parsing.
2067 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2069 if (gDebug>1)
2070 Info("TCling::RegisterModule",
2071 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2073 }
2074
2075
2076 // Make sure we relookup symbols that were search for before we loaded
2077 // their autoparse information. We could be more subtil and remove only
2078 // the failed one or only the one in this module, but for now this is
2079 // better than nothing.
2080 fLookedUpClasses.clear();
2081
2082 // Make sure we do not set off AutoLoading or autoparsing during the
2083 // module registration!
2085
2086 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2088 }
2089 cling::Transaction* T = nullptr;
2090 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2092 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2093 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2094 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2095 assert(cling::Interpreter::kSuccess == compRes &&
2096 "A fwd declaration could not be compiled");
2097 if (compRes!=cling::Interpreter::kSuccess){
2098 Warning("TCling::RegisterModule",
2099 "Problems in declaring string '%s' were encountered.",
2100 fwdDecl.c_str()) ;
2101 continue;
2102 }
2103
2104 // Drill through namespaces recursively until the template is found
2105 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2107 }
2108
2109 }
2110
2111 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2112 // This is used to give Sema the same view on ACLiC'ed files (which
2113 // are then #included through the dictionary) as rootcling had.
2115 if (payloadCode)
2116 code += payloadCode;
2117
2118 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2119 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2120
2121 if (dyLibName.empty()) {
2122 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2123 return;
2124 }
2125
2126 // The triggerFunc may not be in a shared object but in an executable.
2127 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2128
2129 bool wasDlopened = false;
2130
2131 // If this call happens after dlopen has finished (i.e. late registration)
2132 // there is no need to dlopen the library recursively. See ROOT-8437 where
2133 // the dyLibName would correspond to the binary.
2134 if (!lateRegistration) {
2135
2136 if (isSharedLib) {
2137 // We need to open the dictionary shared library, to resolve symbols
2138 // requested by the JIT from it: as the library is currently being dlopen'ed,
2139 // its symbols are not yet reachable from the process.
2140 // Recursive dlopen seems to work just fine.
2141 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2142 if (dyLibHandle) {
2144 wasDlopened = true;
2145 } else {
2147 }
2148 }
2149 } // if (!lateRegistration)
2150
2152 // We now parse the forward declarations. All the classes are then modified
2153 // in order for them to have an external lexical storage.
2154 std::string fwdDeclsCodeLessEnums;
2155 {
2156 // Search for enum forward decls and only declare them if no
2157 // declaration exists yet.
2158 std::string fwdDeclsLine;
2159 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2160 std::vector<std::string> scopes;
2161 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2162 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2163 // We check if the line contains a fwd declaration of an enum
2164 if (enumPos != std::string::npos) {
2165 // We clear the scopes which we may have carried from a previous iteration
2166 scopes.clear();
2167 // We check if the enum is not in a scope. If yes, save its name
2168 // and the names of the enclosing scopes.
2169 if (enumPos != 0) {
2170 // it's enclosed in namespaces. We need to understand what they are
2171 auto nsPos = fwdDeclsLine.find("namespace");
2172 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2173 while (nsPos < enumPos && nsPos != std::string::npos) {
2174 // we have a namespace, let's put it in the collection of scopes
2175 const auto nsNameStart = nsPos + 10;
2176 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2177 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2178 scopes.push_back(nsName);
2179 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2180 }
2181 }
2182 clang::DeclContext* DC = nullptr;
2183 for (auto &&aScope: scopes) {
2184 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2185 if (!DC) {
2186 // No decl context means we have to fwd declare the enum.
2187 break;
2188 }
2189 }
2190 if (scopes.empty() || DC) {
2191 // We know the scope; let's look for the enum. For that, look
2192 // for the *last* closing parentheses of an attribute because
2193 // there can be multiple.
2194 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2195 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2196 posEnumName += 5; // skip "\"))) "
2198 ++posEnumName;
2199 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2200 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2203 // posEnumNameEnd now points to the last character of the name.
2204
2205 std::string enumName = fwdDeclsLine.substr(posEnumName,
2207
2208 if (clang::NamedDecl* enumDecl
2209 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2210 enumName.c_str(), DC)) {
2211 // We have an existing enum decl (forward or definition);
2212 // skip this.
2213 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2214 (void)enumDecl;
2215 continue;
2216 }
2217 }
2218 }
2219
2221 }
2222 }
2223
2224 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2225 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2226 assert(cling::Interpreter::kSuccess == compRes &&
2227 "The forward declarations could not be compiled");
2228 if (compRes!=cling::Interpreter::kSuccess){
2229 Warning("TCling::RegisterModule",
2230 "Problems in compiling forward declarations for module %s: '%s'",
2232 }
2233 else if (T){
2234 // Loop over all decls in the transaction and go through them all
2235 // to mark them properly.
2236 // In order to do that, we first iterate over all the DelayedCallInfos
2237 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2238 // contained in the DelayedCallInfos. For each decl, we traverse.
2239 ExtLexicalStorageAdder elsa;
2240 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2241 cling::Transaction::DelayCallInfo& dci = *dciIt;
2242 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2243 clang::Decl* declPtr = *dit;
2244 elsa.TraverseDecl(declPtr);
2245 }
2246 }
2247 }
2248 }
2249
2250 // Now we register all the headers necessary for the class
2251 // Typical format of the array:
2252 // {"A", "classes.h", "@",
2253 // "vector<A>", "vector", "@",
2254 // "myClass", payloadCode, "@",
2255 // nullptr};
2256
2257 std::string temp;
2258 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2259 temp=*classesHeader;
2260
2261 size_t theTemplateHash = 0;
2262 bool addTemplate = false;
2263 size_t posTemplate = temp.find('<');
2264 if (posTemplate != std::string::npos) {
2265 // Add an entry for the template itself.
2266 std::string templateName = temp.substr(0, posTemplate);
2268 addTemplate = true;
2269 }
2270 size_t theHash = fStringHashFunction(temp);
2271 classesHeader++;
2273 // This is done in order to distinguish headers from files and from the payloadCode
2275 fPayloads.insert(theHash);
2277 }
2278 if (gDebug > 2)
2279 Info("TCling::RegisterModule",
2280 "Adding a header for %s", temp.c_str());
2282 if (addTemplate) {
2285 }
2286 addTemplate = false;
2287 }
2288 }
2289 }
2290 }
2291
2292 clang::Sema &TheSema = fInterpreter->getSema();
2293
2294 bool ModuleWasSuccessfullyLoaded = false;
2295 if (hasCxxModule) {
2296 std::string ModuleName = modulename;
2297 if (llvm::StringRef(modulename).starts_with("lib"))
2298 ModuleName = llvm::StringRef(modulename).substr(3).str();
2299
2300 // In case we are directly loading the library via gSystem->Load() without
2301 // specifying the relevant include paths we should try loading the
2302 // modulemap next to the library location.
2303 clang::Preprocessor &PP = TheSema.getPreprocessor();
2304 std::string ModuleMapName;
2305 if (isACLiC)
2306 ModuleMapName = ModuleName + ".modulemap";
2307 else
2308 ModuleMapName = "module.modulemap";
2309 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2311
2312 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2313 // modules such as GenVector32 because it needs to fall back to GenVector.
2314 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2317 // Only report if we found the module in the modulemap.
2318 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2319 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2320 if (moduleMap.findModule(ModuleName))
2321 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2322 }
2323 }
2324
2326 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2327 // The path dyLibName might not be absolute. This can happen if dyLibName
2328 // is linked to an executable in the same folder.
2329 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2330 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2331 llvm::sys::path::append(pcmFileNameFullPath,
2333 LoadPCM(pcmFileNameFullPath.str().str());
2334 }
2335
2336 { // scope within which diagnostics are de-activated
2337 // For now we disable diagnostics because we saw them already at
2338 // dictionary generation time. That won't be an issue with the PCMs.
2339
2340 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2341
2342#if defined(R__MUST_REVISIT)
2343#if R__MUST_REVISIT(6,2)
2344 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2345#endif
2346#endif
2347
2350
2351 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2352 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2353 if (isACLiC) {
2354 // Register an unload point.
2355 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2356 }
2357
2358 assert(cling::Interpreter::kSuccess == compRes &&
2359 "Payload code of a dictionary could not be parsed correctly.");
2360 if (compRes!=cling::Interpreter::kSuccess) {
2361 Warning("TCling::RegisterModule",
2362 "Problems declaring payload for module %s.", modulename) ;
2363 }
2364 }
2365 }
2366
2367 // Now that all the header have been registered/compiled, let's
2368 // make sure to 'reset' the TClass that have a class init in this module
2369 // but already had their type information available (using information/header
2370 // loaded from other modules or from class rules or from opening a TFile
2371 // or from loading header in a way that did not provoke the loading of
2372 // the library we just loaded).
2374
2376 // __ROOTCLING__ might be pulled in through PCH
2377 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2378 "#undef __ROOTCLING__\n"
2380 "#endif");
2381 }
2382
2383 if (wasDlopened) {
2385 void* dyLibHandle = fRegisterModuleDyLibs.back();
2386 fRegisterModuleDyLibs.pop_back();
2388 }
2389}
2390
2392 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2393 ASTContext &C = CI.getASTContext();
2394
2395 // Do not do anything if we have no global module index.
2396 // FIXME: This is mostly to real with false positives in the TTabCom
2397 // interface for non-modules.
2398 if (!fCxxModulesEnabled)
2399 return;
2400
2401 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2402 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2403 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2404 std::string I = Ident.str();
2405 if (!Idents.Contains(I.data()))
2406 Idents.Add(new TObjString(I.c_str()));
2407 }
2408 }
2409}
2410
2411
2412////////////////////////////////////////////////////////////////////////////////
2413/// Register classes that already existed prior to their dictionary loading
2414/// and that already had a ClassInfo (and thus would not be refresh via
2415/// UpdateClassInfo.
2416
2418{
2419 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2420}
2421
2422////////////////////////////////////////////////////////////////////////////////
2423/// If the dictionary is loaded, we can remove the class from the list
2424/// (otherwise the class might be loaded twice).
2425
2427{
2428 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2429 iterator stop = fClassesToUpdate.end();
2430 for(iterator i = fClassesToUpdate.begin();
2431 i != stop;
2432 ++i)
2433 {
2434 if ( i->first == oldcl ) {
2435 fClassesToUpdate.erase(i);
2436 return;
2437 }
2438 }
2439}
2440
2441
2442////////////////////////////////////////////////////////////////////////////////
2443/// Let cling process a command line.
2444///
2445/// If the command is executed and the error is 0, then the return value
2446/// is the int value corresponding to the result of the executed command
2447/// (float and double return values will be truncated).
2448///
2449
2450// Method for handling the interpreter exceptions.
2451// the MetaProcessor is passing in as argument to teh function, because
2452// cling::Interpreter::CompilationResult is a nested class and it cannot be
2453// forward declared, thus this method cannot be a static member function
2454// of TCling.
2455
2456static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2457 const char* input_line,
2458 cling::Interpreter::CompilationResult& compRes,
2459 cling::Value* result)
2460{
2461 try {
2462 return metaProcessor->process(input_line, compRes, result);
2463 }
2464 catch (cling::InterpreterException& ex)
2465 {
2466 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2467 ex.diagnose();
2468 compRes = cling::Interpreter::kFailure;
2469 }
2470 return 0;
2471}
2472
2473////////////////////////////////////////////////////////////////////////////////
2474
2475bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2476{
2477 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2478 ie->diagnose();
2479 return true;
2480 }
2481 return false;
2482}
2483
2484////////////////////////////////////////////////////////////////////////////////
2485
2487{
2488 // Copy the passed line, it comes from a static buffer in TApplication
2489 // which can be reentered through the Cling evaluation routines,
2490 // which would overwrite the static buffer and we would forget what we
2491 // were doing.
2492 //
2494 if (strstr(line,fantomline)) {
2495 // End-Of-Line action
2496 // See the comment (copied from above):
2497 // It is a "fantom" method to synchronize user keyboard input
2498 // and ROOT prompt line (for WIN32)
2499 // and is implemented by
2500 if (gApplication) {
2501 if (gApplication->IsCmdThread()) {
2503 gROOT->SetLineIsProcessing();
2504
2506
2507 gROOT->SetLineHasBeenProcessed();
2508 }
2509 }
2510 return 0;
2511 }
2512
2514 gGlobalMutex->Lock();
2515 if (!gInterpreterMutex)
2518 }
2520 gROOT->SetLineIsProcessing();
2521
2522 struct InterpreterFlagsRAII {
2523 cling::Interpreter* fInterpreter;
2525
2526 InterpreterFlagsRAII(cling::Interpreter* interp):
2527 fInterpreter(interp),
2528 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2529 {
2530 fInterpreter->enableDynamicLookup(true);
2531 }
2533 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2534 gROOT->SetLineHasBeenProcessed();
2535 }
2537
2538 // A non-zero returned value means the given line was
2539 // not a complete statement.
2540 int indent = 0;
2541 // This will hold the resulting value of the evaluation the given line.
2542 cling::Value result;
2543 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2544 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2545 !strncmp(sLine.Data(), ".X", 2)) {
2546 // If there was a trailing "+", then CINT compiled the code above,
2547 // and we will need to strip the "+" before passing the line to cling.
2550 TString arguments;
2551 TString io;
2553 aclicMode, arguments, io);
2554 if (aclicMode.Length()) {
2555 // Remove the leading '+'
2556 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2557 aclicMode[0]='k'; // We always want to keep the .so around.
2558 if (aclicMode[1]=='+') {
2559 // We have a 2nd +
2560 aclicMode[1]='f'; // We want to force the recompilation.
2561 }
2563 // ACLiC failed.
2564 compRes = cling::Interpreter::kFailure;
2565 } else {
2566 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2567 // if execution was requested.
2568
2569 if (arguments.Length() == 0) {
2570 arguments = "()";
2571 }
2572 // We need to remove the extension.
2573 Ssiz_t ext = fname.Last('.');
2574 if (ext != kNPOS) {
2575 fname.Remove(ext);
2576 }
2577 const char *function = gSystem->BaseName(fname);
2578 mod_line = function + arguments + io;
2580 }
2581 }
2582 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2583 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2584 if (gSystem->Load(fname) < 0) {
2585 // Loading failed.
2586 compRes = cling::Interpreter::kFailure;
2587 } else {
2588 if (arguments.Length() == 0) {
2589 arguments = "()";
2590 }
2591 // We need to remove the extension. (*.so or *.dll)
2592 Ssiz_t ext = fname.Last('.');
2593 if (ext != kNPOS) {
2594 fname.Remove(ext);
2595 }
2596 // Now we try to find the 'main' function to run within this shared library
2597 // We distinguish two cases: a library.so with a function library(args),
2598 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2599 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2600 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2601 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2602 ext = fname.Last('_');
2603 if (ext != kNPOS) {
2604 fname.Remove(ext);
2605 }
2606 }
2607 const char *function = gSystem->BaseName(fname);
2608 mod_line = function + arguments + io;
2610 }
2611 } else {
2612 // neither ACLiC nor run shared-library (.x)
2613 size_t unnamedMacroOpenCurly;
2614 {
2615 std::string code;
2616 std::string codeline;
2617 // Windows requires std::ifstream::binary to properly handle
2618 // CRLF and LF line endings
2619 std::ifstream in(fname, std::ifstream::binary);
2620 while (in) {
2621 std::getline(in, codeline);
2622 code += codeline + "\n";
2623 }
2625 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2626 }
2627
2628 fCurExecutingMacros.push_back(fname);
2629 if (unnamedMacroOpenCurly != std::string::npos) {
2630 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2632 } else {
2633 // No DynLookup for .x, .L of named macros.
2634 fInterpreter->enableDynamicLookup(false);
2636 }
2637 fCurExecutingMacros.pop_back();
2638 }
2639 } // .L / .X / .x
2640 else {
2641 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2642 // explicitly ignore .autodict without having to support it
2643 // in cling.
2644
2645 // Turn off autoparsing if this is an include directive
2646 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2650 } else {
2652 }
2653 }
2654 }
2655 if (result.isValid())
2657 if (indent) {
2658 if (error)
2659 *error = kProcessing;
2660 return 0;
2661 }
2662 if (error) {
2663 switch (compRes) {
2664 case cling::Interpreter::kSuccess: *error = kNoError; break;
2665 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2666 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2667 }
2668 }
2669 if (compRes == cling::Interpreter::kSuccess
2670 && result.isValid()
2671 && !result.isVoid())
2672 {
2673 return result.castAs<Longptr_t>();
2674 }
2675 return 0;
2676}
2677
2678////////////////////////////////////////////////////////////////////////////////
2679/// No-op; see TRint instead.
2680
2682{
2683}
2684
2685////////////////////////////////////////////////////////////////////////////////
2686/// \brief Add a directory to the list of directories in which the
2687/// interpreter looks for include files.
2688/// \param[in] path The path to the directory.
2689/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2690/// \b NOT supported.
2691/// \warning Only the path to the directory should be specified, without
2692/// prepending the \c -I prefix, i.e.
2693/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2694/// \c -I prefix is used it will be ignored.
2695void TCling::AddIncludePath(const char *path)
2696{
2698 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2699 // gCling->AddIncludePath() does not! Work around that inconsistency:
2700 if (path[0] == '-' && path[1] == 'I')
2701 path += 2;
2702 TString sPath(path);
2704#ifdef _MSC_VER
2705 if (sPath.BeginsWith("/")) {
2706 char drive[3];
2707 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2708 sPath.Prepend(drive);
2709 }
2710#endif
2711 fInterpreter->AddIncludePath(sPath.Data());
2712}
2713
2714////////////////////////////////////////////////////////////////////////////////
2715/// Visit all members over members, recursing over base classes.
2716
2718 const TClass* cl, Bool_t isTransient)
2719{
2720 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2721 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
2723 }
2724
2725 if (!cl || cl->GetCollectionProxy()) {
2726 // We do not need to investigate the content of the STL
2727 // collection, they are opaque to us (and details are
2728 // uninteresting).
2729 return;
2730 }
2731
2732 static const TClassRef clRefString("std::string");
2733 if (clRefString == cl) {
2734 // We stream std::string without going through members..
2735 return;
2736 }
2737
2738 if (TClassEdit::IsStdArray(cl->GetName())) {
2739 // We treat std arrays as C arrays
2740 return;
2741 }
2742
2743 if (TClassEdit::IsUniquePtr(cl->GetName())) {
2744 // Ignore error caused by the inside of std::unique_ptr
2745 // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer
2746 // which checks the number of elements in the GetListOfRealData.
2747 // If this usage is removed, this can be replaced with a return statement.
2748 // See https://github.com/root-project/root/issues/13574
2749 isTransient = true;
2750 }
2751
2752 const char* cobj = (const char*) obj; // for ptr arithmetics
2753
2754 // Treat the case of std::complex in a special manner. We want to enforce
2755 // the layout of a stl implementation independent class, which is the
2756 // complex as implemented in ROOT5.
2757
2758 // A simple lambda to simplify the code
2759 auto inspInspect = [&] (ptrdiff_t offset){
2760 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2761 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2762 };
2763
2765 switch(complexType) {
2767 {
2768 break;
2769 }
2771 {
2772 inspInspect(sizeof(float));
2773 return;
2774 }
2776 {
2777 inspInspect(sizeof(double));
2778 return;
2779 }
2781 {
2782 inspInspect(sizeof(int));
2783 return;
2784 }
2786 {
2787 inspInspect(sizeof(long));
2788 return;
2789 }
2790 }
2791
2792 static clang::PrintingPolicy
2793 printPol(fInterpreter->getCI()->getLangOpts());
2794 if (printPol.Indentation) {
2795 // not yet initialized
2796 printPol.Indentation = 0;
2797 printPol.SuppressInitializers = true;
2798 }
2799
2800 const char* clname = cl->GetName();
2801 // Printf("Inspecting class %s\n", clname);
2802
2803 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2804 const clang::Decl *scopeDecl = nullptr;
2805 const clang::Type *recordType = nullptr;
2806
2807 if (cl->GetClassInfo()) {
2809 scopeDecl = clingCI->GetDecl();
2810 recordType = clingCI->GetType();
2811 } else {
2812 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2813 // Diags will complain about private classes:
2814 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2815 &recordType);
2816 }
2817 if (!scopeDecl) {
2818 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2819 return;
2820 }
2821 const clang::CXXRecordDecl* recordDecl
2822 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2823 if (!recordDecl) {
2824 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2825 return;
2826 }
2827
2828 {
2829 // Force possible deserializations first. We need to have no pending
2830 // Transaction when passing control flow to the inspector below (ROOT-7779).
2831 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2832
2833 astContext.getASTRecordLayout(recordDecl);
2834
2835 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2836 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2837 }
2838
2839 const clang::ASTRecordLayout& recLayout
2840 = astContext.getASTRecordLayout(recordDecl);
2841
2842 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2843 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2844 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2845 // cl->GetName());
2846 // }
2847 if (cl->Size() != recLayout.getSize().getQuantity()) {
2848 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2849 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2850 }
2851
2852 unsigned iNField = 0;
2853 // iterate over fields
2854 // FieldDecls are non-static, else it would be a VarDecl.
2855 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2856 eField = recordDecl->field_end(); iField != eField;
2857 ++iField, ++iNField) {
2858
2859
2860 clang::QualType memberQT = iField->getType();
2861 if (recordType) {
2862 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2864 }
2865 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2866 if (memberQT.isNull()) {
2867 std::string memberName;
2868 llvm::raw_string_ostream stream(memberName);
2869 // Don't trigger fopen of the source file to count lines:
2870 printPol.AnonymousTagLocations = false;
2871 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2872 stream.flush();
2873 Error("InspectMembers",
2874 "Cannot retrieve QualType for member %s while inspecting class %s",
2875 memberName.c_str(), clname);
2876 continue; // skip member
2877 }
2878 const clang::Type* memType = memberQT.getTypePtr();
2879 if (!memType) {
2880 std::string memberName;
2881 llvm::raw_string_ostream stream(memberName);
2882 // Don't trigger fopen of the source file to count lines:
2883 printPol.AnonymousTagLocations = false;
2884 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2885 stream.flush();
2886 Error("InspectMembers",
2887 "Cannot retrieve Type for member %s while inspecting class %s",
2888 memberName.c_str(), clname);
2889 continue; // skip member
2890 }
2891
2892 const clang::Type* memNonPtrType = memType;
2893 Bool_t ispointer = false;
2894 if (memNonPtrType->isPointerType()) {
2895 ispointer = true;
2896 clang::QualType ptrQT
2897 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2898 if (recordType) {
2899 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2901 }
2902 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2903 if (ptrQT.isNull()) {
2904 std::string memberName;
2905 llvm::raw_string_ostream stream(memberName);
2906 // Don't trigger fopen of the source file to count lines:
2907 printPol.AnonymousTagLocations = false;
2908 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2909 stream.flush();
2910 Error("InspectMembers",
2911 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2912 memberName.c_str(), clname);
2913 continue; // skip member
2914 }
2915 memNonPtrType = ptrQT.getTypePtr();
2916 }
2917
2918 // assemble array size(s): "[12][4][]"
2919 llvm::SmallString<8> arraySize;
2920 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2921 unsigned arrLevel = 0;
2922 bool haveErrorDueToArray = false;
2923 while (arrType) {
2924 ++arrLevel;
2925 arraySize += '[';
2926 const clang::ConstantArrayType* constArrType =
2927 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2928 if (constArrType) {
2929 constArrType->getSize().toStringUnsigned(arraySize);
2930 }
2931 arraySize += ']';
2932 clang::QualType subArrQT = arrType->getElementType();
2933 if (subArrQT.isNull()) {
2934 std::string memberName;
2935 llvm::raw_string_ostream stream(memberName);
2936 // Don't trigger fopen of the source file to count lines:
2937 printPol.AnonymousTagLocations = false;
2938 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2939 stream.flush();
2940 Error("InspectMembers",
2941 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2942 arrLevel, subArrQT.getAsString(printPol).c_str(),
2943 memberName.c_str(), clname);
2944 haveErrorDueToArray = true;
2945 break;
2946 }
2947 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2948 }
2949 if (haveErrorDueToArray) {
2950 continue; // skip member
2951 }
2952
2953 // construct member name
2954 std::string fieldName;
2955 if (memType->isPointerType()) {
2956 fieldName = "*";
2957 }
2958
2959 // Check if this field has a custom ioname, if not, just use the one of the decl
2960 std::string ioname(iField->getName());
2962 fieldName += ioname;
2963 fieldName += arraySize;
2964
2965 // get member offset
2966 // NOTE currently we do not support bitfield and do not support
2967 // member that are not aligned on 'bit' boundaries.
2968 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2969 ptrdiff_t fieldOffset = offset.getQuantity();
2970
2971 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2972 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2973 // R__insp.InspectMember(fName, "fName.");
2974 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2975
2976 // If the class has a custom streamer and the type of the filed is a
2977 // private enum, struct or class, skip it.
2978 if (!insp.IsTreatingNonAccessibleTypes()){
2979 auto iFiledQtype = iField->getType();
2980 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2981 auto declAccess = tagDecl->getAccess();
2983 continue;
2984 }
2985 }
2986 }
2987
2988 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2989
2990 if (!ispointer) {
2991 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2992 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2993 // nested objects get an extra call to InspectMember
2994 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2995 std::string sFieldRecName;
2998 clang::QualType(memNonPtrType,0),
2999 *fInterpreter,
3001 }
3002
3003 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3004 // if we can not find the member (which should not really happen),
3005 // let's consider it transient.
3006 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3007 if (!mbr || !mbr->IsPersistent())
3008 insp.IncrementNestedTransient();
3009 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3010 (fieldName + '.').c_str(), transient);
3011 if (!mbr || !mbr->IsPersistent())
3012 insp.DecrementNestedTransient();
3013
3014 }
3015 }
3016 } // loop over fields
3017
3018 // inspect bases
3019 // TNamed::ShowMembers(R__insp);
3020 unsigned iNBase = 0;
3021 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3022 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3023 iBase != eBase; ++iBase, ++iNBase) {
3024 clang::QualType baseQT = iBase->getType();
3025 if (baseQT.isNull()) {
3026 Error("InspectMembers",
3027 "Cannot find QualType for base number %d while inspecting class %s",
3028 iNBase, clname);
3029 continue;
3030 }
3031 const clang::CXXRecordDecl* baseDecl
3032 = baseQT->getAsCXXRecordDecl();
3033 if (!baseDecl) {
3034 Error("InspectMembers",
3035 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3036 iNBase, clname);
3037 continue;
3038 }
3039 TClass* baseCl=nullptr;
3040 std::string sBaseName;
3041 // Try with the DeclId
3042 std::vector<TClass*> foundClasses;
3044 if (foundClasses.size()==1){
3046 } else {
3047 // Try with the normalised Name, as a fallback
3048 if (!baseCl){
3050 baseQT,
3051 *fInterpreter,
3054 }
3055 }
3056
3057 if (!baseCl){
3058 std::string qualNameForDiag;
3060 Error("InspectMembers",
3061 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3062 continue;
3063 }
3064
3065 int64_t baseOffset;
3066 if (iBase->isVirtual()) {
3067 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
3068 if (!isTransient) {
3069 Error("InspectMembers",
3070 "Base %s of class %s is virtual but no object provided",
3071 sBaseName.c_str(), clname);
3072 }
3074 } else {
3075 // We have an object to determine the vbase offset.
3077 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3078 if (ci && baseCi) {
3079 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3080 true /*isDerivedObj*/);
3081 if (baseOffset == -1) {
3082 Error("InspectMembers",
3083 "Error calculating offset of virtual base %s of class %s",
3084 sBaseName.c_str(), clname);
3085 }
3086 } else {
3087 Error("InspectMembers",
3088 "Cannot calculate offset of virtual base %s of class %s",
3089 sBaseName.c_str(), clname);
3090 continue;
3091 }
3092 }
3093 } else {
3094 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3095 }
3096 // TOFIX: baseCl can be null here!
3097 if (baseCl->IsLoaded()) {
3098 // For loaded class, CallShowMember will (especially for TObject)
3099 // call the virtual ShowMember rather than the class specific version
3100 // resulting in an infinite recursion.
3102 } else {
3103 baseCl->CallShowMembers(cobj + baseOffset,
3104 insp, isTransient);
3105 }
3106 } // loop over bases
3107}
3108
3109////////////////////////////////////////////////////////////////////////////////
3110/// Check if constructor exited correctly, ie the instance is in a valid state
3111/// \return true if there is a compiler instance available, false otherwise
3113{
3114 return fInterpreter->getCI() != nullptr;
3115}
3116
3117////////////////////////////////////////////////////////////////////////////////
3118/// Reset the interpreter internal state in case a previous action was not correctly
3119/// terminated.
3120
3122{
3123 // No-op there is not equivalent state (to be cleared) in Cling.
3124}
3125
3126////////////////////////////////////////////////////////////////////////////////
3127/// Delete existing temporary values.
3128
3130{
3131 // No-op for cling due to cling::Value.
3132}
3133
3134////////////////////////////////////////////////////////////////////////////////
3135/// Declare code to the interpreter, without any of the interpreter actions
3136/// that could trigger a re-interpretation of the code. I.e. make cling
3137/// behave like a compiler: no dynamic lookup, no input wrapping for
3138/// subsequent execution, no automatic provision of declarations but just a
3139/// plain `#include`.
3140/// Returns true on success, false on failure.
3141
3142bool TCling::Declare(const char* code)
3143{
3145
3148
3149 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3150 fInterpreter->enableDynamicLookup(false);
3151 bool oldRawInput = fInterpreter->isRawInputEnabled();
3152 fInterpreter->enableRawInput(true);
3153
3154 Bool_t ret = LoadText(code);
3155
3156 fInterpreter->enableRawInput(oldRawInput);
3157 fInterpreter->enableDynamicLookup(oldDynLookup);
3158 return ret;
3159}
3160
3161////////////////////////////////////////////////////////////////////////////////
3162/// It calls a "fantom" method to synchronize user keyboard input
3163/// and ROOT prompt line.
3164
3169
3170// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3171// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3172// was already taking a lock.
3173static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3174{
3175 // Check shared library.
3178 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3179 return false;
3180}
3181
3187
3188////////////////////////////////////////////////////////////////////////////////
3189/// Return true if ROOT has cxxmodules pcm for a given library name.
3190// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3192{
3193 llvm::StringRef ModuleName(libname);
3194 ModuleName = llvm::sys::path::stem(ModuleName);
3195 ModuleName.consume_front("lib");
3196
3197 // FIXME: In case when the modulemap is not yet loaded we will return the
3198 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3199 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3200 // which may happen after calling this interface. Maybe we should also check
3201 // if there is a Event.pcm file and a module.modulemap, load it and return
3202 // true.
3203 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3204 clang::Module *M = moduleMap.findModule(ModuleName);
3205 return M && !M->IsUnimportable && M->getASTFile();
3206}
3207
3208////////////////////////////////////////////////////////////////////////////////
3209/// Return true if the file has already been loaded by cint.
3210/// We will try in this order:
3211/// actual filename
3212/// filename as a path relative to
3213/// the include path
3214/// the shared library path
3215
3217{
3219
3220 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3221 // cling::DynamicLibraryManager.
3222
3223 std::string file_name = filename;
3224 size_t at = std::string::npos;
3225 while ((at = file_name.find("/./")) != std::string::npos)
3226 file_name.replace(at, 3, "/");
3227
3228 std::string filesStr = "";
3229 llvm::raw_string_ostream filesOS(filesStr);
3230 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3231 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3232 filesOS.flush();
3233
3234 llvm::SmallVector<llvm::StringRef, 100> files;
3235 llvm::StringRef(filesStr).split(files, "\n");
3236
3237 std::set<std::string> fileMap;
3238 llvm::StringRef file_name_ref(file_name);
3239 // Fill fileMap; return early on exact match.
3241 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3242 if ((*iF) == file_name_ref) return kTRUE; // exact match
3243 fileMap.insert(iF->str());
3244 }
3245
3246 if (fileMap.empty()) return kFALSE;
3247
3248 // Check MacroPath.
3249 TString sFilename(file_name.c_str());
3251 && fileMap.count(sFilename.Data())) {
3252 return kTRUE;
3253 }
3254
3255 // Check IncludePath.
3256 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3257 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3258 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3259 while (incPath.Index(" :") != -1) {
3260 incPath.ReplaceAll(" :", ":");
3261 }
3262 incPath.Prepend(".:");
3263 sFilename = file_name.c_str();
3265 && fileMap.count(sFilename.Data())) {
3266 return kTRUE;
3267 }
3268
3269 // Check shared library.
3270 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3271 return kTRUE;
3272
3273 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3274 clang::ConstSearchDirIterator *CurDir = nullptr;
3275 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3276 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3277 auto FE = HS.LookupFile(file_name.c_str(),
3278 clang::SourceLocation(),
3279 /*isAngled*/ false,
3280 /*FromDir*/ nullptr, CurDir,
3281 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3282 clang::DirectoryEntryRef>>(),
3283 /*SearchPath*/ nullptr,
3284 /*RelativePath*/ nullptr,
3285 /*RequestingModule*/ nullptr,
3286 /*SuggestedModule*/ nullptr,
3287 /*IsMapped*/ nullptr,
3288 /*IsFrameworkFound*/ nullptr,
3289 /*SkipCache*/ false,
3290 /*BuildSystemModule*/ false,
3291 /*OpenFile*/ false,
3292 /*CacheFail*/ false);
3293 if (FE) {
3294 // check in the source manager if the file is actually loaded
3295 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3296 // this works only with header (and source) files...
3297 clang::FileID FID = SM.translateFile(*FE);
3298 if (!FID.isInvalid() && FID.getHashValue() == 0)
3299 return kFALSE;
3300 else {
3301 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3302 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3303 return kFALSE;
3304 if (!FID.isInvalid())
3305 return kTRUE;
3306 }
3307 // ...then check shared library again, but with full path now
3308 sFilename = FE->getName().str();
3310 && fileMap.count(sFilename.Data())) {
3311 return kTRUE;
3312 }
3313 }
3314 return kFALSE;
3315}
3316
3317
3318#if defined(R__MACOSX)
3319
3320////////////////////////////////////////////////////////////////////////////////
3321/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3322/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3323/// to `-lFOO` such that it can be passed to the linker.
3324/// This is a unique feature of macOS 11.
3325
3326static bool R__UpdateLibFileForLinking(TString &lib)
3327{
3328 const char *mapfile = nullptr;
3329#if __x86_64__
3330 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3331#elif __arm64__
3332 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3333#else
3334 #error unsupported architecture
3335#endif
3336 if (std::ifstream cacheMap{mapfile}) {
3337 std::string line;
3338 while (getline(cacheMap, line)) {
3339 if (line.find(lib) != std::string::npos) {
3340 lib.ReplaceAll("/usr/lib/lib","-l");
3341 lib.ReplaceAll(".dylib","");
3342 return true;
3343 }
3344 }
3345 return false;
3346 }
3347 return false;
3348}
3349#endif // R__MACOSX
3350
3351#if defined (R__LINUX) || defined (R__FBSD)
3352
3353////////////////////////////////////////////////////////////////////////////////
3354/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3355/// Collects opened libraries.
3356
3357static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3358{
3359 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3360 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3361
3362 auto newLibs = static_cast<std::vector<std::string>*>(data);
3363 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3364 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3365 if (info->dlpi_name && info->dlpi_name[0]
3366#if defined(R__FBSD)
3367 //skip the executable (with null addr)
3368 && info->dlpi_addr
3369 //has no path
3370 && strncmp(info->dlpi_name, "[vdso]", 6)
3371 //the linker does not like to be mmapped
3372 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3373 //with error message "mmap of entire address space failed: Cannot allocate memory"
3374 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3375#endif
3376 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3377 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3378 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3379 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3380 newLibs->emplace_back(info->dlpi_name);
3381 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3382 }
3383 // No matter what the doc says, return != 0 means "stop the iteration".
3384 return 0;
3385}
3386
3387#endif // R__LINUX || R__FBSD
3388
3389
3390////////////////////////////////////////////////////////////////////////////////
3391
3393{
3394#if defined(R__WIN32) || defined(__CYGWIN__)
3395 HMODULE hModules[1024];
3396 void *hProcess;
3397 unsigned long cbModules;
3398 unsigned int i;
3399 hProcess = (void *)::GetCurrentProcess();
3401 // start at 1 to skip the executable itself
3402 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3403 static const int bufsize = 260;
3404 wchar_t winname[bufsize];
3405 char posixname[bufsize];
3407#if defined(__CYGWIN__)
3409#else
3410 std::wstring wpath = winname;
3411 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3412 string path(wpath.begin(), wpath.end());
3413 strncpy(posixname, path.c_str(), bufsize);
3414#endif
3417 }
3418 }
3419#elif defined(R__MACOSX)
3420 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3421 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3422
3424 // Skip non-dylibs
3425 if (mh->filetype == MH_DYLIB) {
3426 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3428 }
3429 }
3430
3431 ++imageIndex;
3432 }
3433 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3434#elif defined(R__LINUX) || defined(R__FBSD)
3435 // fPrevLoadedDynLibInfo is unused on Linux.
3436 (void) fPrevLoadedDynLibInfo;
3437
3438 std::vector<std::string> newLibs;
3440 for (auto &&lib: newLibs)
3441 RegisterLoadedSharedLibrary(lib.c_str());
3442#else
3443 Error("TCling::UpdateListOfLoadedSharedLibraries",
3444 "Platform not supported!");
3445#endif
3446}
3447
3448namespace {
3449template <int N>
3450static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3451 return !strncmp(haystack, needle, N - 1);
3452}
3453}
3454
3455////////////////////////////////////////////////////////////////////////////////
3456/// Register a new shared library name with the interpreter; add it to
3457/// fSharedLibs.
3458
3460{
3461 // Ignore NULL filenames, aka "the process".
3462 if (!filename) return;
3463
3464 // Tell the interpreter that this library is available; all libraries can be
3465 // used to resolve symbols.
3466 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3467 if (!DLM->isLibraryLoaded(filename)) {
3468 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3469 }
3470
3471#if defined(R__MACOSX)
3472 // Check that this is not a system library that does not exist on disk.
3473 auto lenFilename = strlen(filename);
3474 auto isInMacOSSystemDir = [](const char *fn) {
3475 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3476 };
3477 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3478
3479 // These we should not link with (e.g. because they forward to .tbd):
3480 || StartsWithStrLit(filename, "/usr/lib/system/")
3481 || StartsWithStrLit(filename, "/usr/lib/libc++")
3482 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3483 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3484 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3485 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3486 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3487 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3488 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3489 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3490 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3491 || StartsWithStrLit(filename, "/usr/lib/libauto")
3492 || StartsWithStrLit(filename, "/usr/lib/libcups")
3493 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3494 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3495 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3496 || StartsWithStrLit(filename, "/usr/lib/libpam")
3497 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3498 || StartsWithStrLit(filename, "/usr/lib/libextension")
3499 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3500 || StartsWithStrLit(filename, "/usr/lib/liboah")
3501 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3502 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3503 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3504 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3505
3506 // The system lib is likely in macOS's blob.
3508
3509 // "Link against the umbrella framework 'System.framework' instead"
3510 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3511 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3512 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3513
3514 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3515 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3516 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3517 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3518 return;
3521 filename = sFileName.Data();
3522#elif defined(__CYGWIN__)
3523 // Check that this is not a system library
3524 static const int bufsize = 260;
3525 char posixwindir[bufsize];
3526 char *windir = getenv("WINDIR");
3527 if (windir)
3529 else
3530 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3531 if (strstr(filename, posixwindir) ||
3532 strstr(filename, "/usr/bin/cyg"))
3533 return;
3534#elif defined(R__WIN32)
3535 if (strstr(filename, "/Windows/"))
3536 return;
3537#elif defined (R__LINUX)
3538 if (strstr(filename, "/ld-linux")
3539 || strstr(filename, "linux-gnu/")
3540 || strstr(filename, "/libstdc++.")
3541 || strstr(filename, "/libgcc")
3542 || strstr(filename, "/libc.")
3543 || strstr(filename, "/libdl.")
3544 || strstr(filename, "/libm."))
3545 return;
3546#endif
3547 // Update string of available libraries.
3548 if (!fSharedLibs.IsNull()) {
3549 fSharedLibs.Append(" ");
3550 }
3552}
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Load a library file in cling's memory.
3556/// if 'system' is true, the library is never unloaded.
3557/// Return 0 on success, -1 on failure.
3558
3560{
3561 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3562
3563 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3565 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3566 std::string canonLib = DLM->lookupLibrary(filename);
3567 cling::DynamicLibraryManager::LoadLibResult res
3568 = cling::DynamicLibraryManager::kLoadLibNotFound;
3569 if (!canonLib.empty()) {
3570 if (system)
3571 res = DLM->loadLibrary(filename, system, true);
3572 else {
3573 // For the non system libs, we'd like to be able to unload them.
3574 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3575 cling::Interpreter::CompilationResult compRes;
3576 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3577 if (compRes == cling::Interpreter::kSuccess)
3578 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3579 }
3580 }
3581
3582 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3584 }
3585 switch (res) {
3586 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3587 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3588 default: break;
3589 };
3590 return -1;
3591}
3592
3593////////////////////////////////////////////////////////////////////////////////
3594/// Load a macro file in cling's memory.
3595
3596void TCling::LoadMacro(const char* filename, EErrorCode* error)
3597{
3598 ProcessLine(Form(".L %s", filename), error);
3599}
3600
3601////////////////////////////////////////////////////////////////////////////////
3602/// Let cling process a command line asynch.
3603
3605{
3606 return ProcessLine(line, error);
3607}
3608
3609////////////////////////////////////////////////////////////////////////////////
3610/// Let cling process a command line synchronously, i.e we are waiting
3611/// it will be finished.
3612
3614{
3616 if (gApplication) {
3617 if (gApplication->IsCmdThread()) {
3618 return ProcessLine(line, error);
3619 }
3620 return 0;
3621 }
3622 return ProcessLine(line, error);
3623}
3624
3625////////////////////////////////////////////////////////////////////////////////
3626/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3627/// however not declarations, like "Int_t x;").
3628
3630{
3631#ifdef R__WIN32
3632 // Test on ApplicationImp not being 0 is needed because only at end of
3633 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3634 // we can not use it.
3636 while (gROOT->IsLineProcessing() && !gApplication) {
3637 Warning("Calc", "waiting for cling thread to free");
3638 gSystem->Sleep(500);
3639 }
3640 gROOT->SetLineIsProcessing();
3641 }
3642#endif // R__WIN32
3644 if (error) {
3645 *error = TInterpreter::kNoError;
3646 }
3647 cling::Value valRef;
3648 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3649 try {
3650 cr = fInterpreter->evaluate(line, valRef);
3651 }
3652 catch (cling::InterpreterException& ex)
3653 {
3654 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3655 ex.diagnose();
3656 cr = cling::Interpreter::kFailure;
3657 }
3658
3659 if (cr != cling::Interpreter::kSuccess) {
3660 // Failure in compilation.
3661 if (error) {
3662 // Note: Yes these codes are weird.
3664 }
3665 return 0L;
3666 }
3667 if (!valRef.isValid()) {
3668 // Failure at runtime.
3669 if (error) {
3670 // Note: Yes these codes are weird.
3671 *error = TInterpreter::kDangerous;
3672 }
3673 return 0L;
3674 }
3675
3676 if (valRef.isVoid()) {
3677 return 0;
3678 }
3679
3681#ifdef R__WIN32
3683 gROOT->SetLineHasBeenProcessed();
3684 }
3685#endif // R__WIN32
3686 return valRef.castAs<Longptr_t>();
3687}
3688
3689////////////////////////////////////////////////////////////////////////////////
3690/// Set a getline function to call when input is needed.
3691
3692void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3693 void (*histaddFunc)(const char* line))
3694{
3695 // If cling offers a replacement for G__pause(), it would need to
3696 // also offer a way to customize at least the history recording.
3697
3698#if defined(R__MUST_REVISIT)
3699#if R__MUST_REVISIT(6,2)
3700 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3701#endif
3702#endif
3703}
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// Helper function to increase the internal Cling count of transactions
3707/// that change the AST.
3708
3709Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3710{
3712
3713 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3714 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3715 || T.macros_begin() != T.macros_end()
3716 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3718 return true;
3719 }
3720 return false;
3721}
3722
3723////////////////////////////////////////////////////////////////////////////////
3724/// Delete object from cling symbol table so it can not be used anymore.
3725/// cling objects are always on the heap.
3726
3728{
3729 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3730 // put in place the Read/Write part here. Keeping the write lock
3731 // here is 'catasptrophic' for scaling as it means that ALL calls
3732 // to RecursiveRemove will take the write lock and performance
3733 // of many threads trying to access the write lock at the same
3734 // time is relatively bad.
3736 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3737 // (but isn't at the moment).
3738 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3739 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3740 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3742 DeleteGlobal(obj);
3743 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3744 }
3745 }
3746}
3747
3748////////////////////////////////////////////////////////////////////////////////
3749/// Pressing Ctrl+C should forward here. In the case where we have had
3750/// continuation requested we must reset it.
3751
3753{
3754 fMetaProcessor->cancelContinuation();
3755 // Reset the Cling state to the state saved by the last call to
3756 // TCling::SaveContext().
3757#if defined(R__MUST_REVISIT)
3758#if R__MUST_REVISIT(6,2)
3760 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3761#endif
3762#endif
3763}
3764
3765////////////////////////////////////////////////////////////////////////////////
3766/// Reset the Cling state to its initial state.
3767
3769{
3770#if defined(R__MUST_REVISIT)
3771#if R__MUST_REVISIT(6,2)
3773 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3774#endif
3775#endif
3776}
3777
3778////////////////////////////////////////////////////////////////////////////////
3779/// Reset in Cling the list of global variables to the state saved by the last
3780/// call to TCling::SaveGlobalsContext().
3781///
3782/// Note: Right now, all we do is run the global destructors.
3783
3785{
3787 // TODO:
3788 // Here we should iterate over the transactions (N-3) and revert.
3789 // N-3 because the first three internal to cling.
3790
3791 fInterpreter->runAndRemoveStaticDestructors();
3792}
3793
3794////////////////////////////////////////////////////////////////////////////////
3795/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3796/// call to TCling::SaveGlobalsContext().
3797
3799{
3800#if defined(R__MUST_REVISIT)
3801#if R__MUST_REVISIT(6,2)
3803 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3804#endif
3805#endif
3806}
3807
3808////////////////////////////////////////////////////////////////////////////////
3809/// Rewind Cling dictionary to the point where it was before executing
3810/// the current macro. This function is typically called after SEGV or
3811/// ctlr-C after doing a longjmp back to the prompt.
3812
3814{
3815#if defined(R__MUST_REVISIT)
3816#if R__MUST_REVISIT(6,2)
3818 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3819#endif
3820#endif
3821}
3822
3823////////////////////////////////////////////////////////////////////////////////
3824/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3825/// Returns 1 in case of success and 0 in case object was not in table.
3826
3828{
3829#if defined(R__MUST_REVISIT)
3830#if R__MUST_REVISIT(6,2)
3832 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3833#endif
3834#endif
3835 return 0;
3836}
3837
3838////////////////////////////////////////////////////////////////////////////////
3839/// Undeclare obj called name.
3840/// Returns 1 in case of success, 0 for failure.
3841
3843{
3844#if defined(R__MUST_REVISIT)
3845#if R__MUST_REVISIT(6,2)
3846 Warning("DeleteVariable","should do more that just reseting the value to zero");
3847#endif
3848#endif
3849
3851 llvm::StringRef srName(name);
3852 const char* unscopedName = name;
3853 llvm::StringRef::size_type posScope = srName.rfind("::");
3854 const clang::DeclContext* declCtx = nullptr;
3855 if (posScope != llvm::StringRef::npos) {
3856 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3857 const clang::Decl* scopeDecl
3858 = lh.findScope(srName.substr(0, posScope),
3859 cling::LookupHelper::WithDiagnostics);
3860 if (!scopeDecl) {
3861 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3862 name);
3863 return 0;
3864 }
3865 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3866 if (!declCtx) {
3867 Error("DeleteVariable",
3868 "Enclosing scope for variable %s is not a declaration context",
3869 name);
3870 return 0;
3871 }
3872 unscopedName += posScope + 2;
3873 }
3874 // Could trigger deserialization of decls.
3875 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3876 clang::NamedDecl* nVarDecl
3877 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3878 if (!nVarDecl) {
3879 Error("DeleteVariable", "Unknown variable %s", name);
3880 return 0;
3881 }
3882 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3883 if (!varDecl) {
3884 Error("DeleteVariable", "Entity %s is not a variable", name);
3885 return 0;
3886 }
3887
3888 clang::QualType qType = varDecl->getType();
3889 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3890 // Cannot set a reference's address to nullptr; the JIT can place it
3891 // into read-only memory (ROOT-7100).
3892 if (type->isPointerType()) {
3893 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3894 // set pointer to invalid.
3895 if (ppInt) *ppInt = nullptr;
3896 }
3897 return 1;
3898}
3899
3900////////////////////////////////////////////////////////////////////////////////
3901/// Save the current Cling state.
3902
3904{
3905#if defined(R__MUST_REVISIT)
3906#if R__MUST_REVISIT(6,2)
3908 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3909#endif
3910#endif
3911}
3912
3913////////////////////////////////////////////////////////////////////////////////
3914/// Save the current Cling state of global objects.
3915
3917{
3918#if defined(R__MUST_REVISIT)
3919#if R__MUST_REVISIT(6,2)
3921 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3922#endif
3923#endif
3924}
3925
3926////////////////////////////////////////////////////////////////////////////////
3927/// No op: see TClingCallbacks (used to update the list of globals)
3928
3932
3933////////////////////////////////////////////////////////////////////////////////
3934/// No op: see TClingCallbacks (used to update the list of global functions)
3935
3939
3940////////////////////////////////////////////////////////////////////////////////
3941/// No op: see TClingCallbacks (used to update the list of types)
3942
3944{
3945}
3946
3947////////////////////////////////////////////////////////////////////////////////
3948/// Check in what order the member of a tuple are layout.
3949enum class ETupleOrdering {
3950 kAscending,
3953};
3954
3960
3966
3968{
3969 std::tuple<int,double> value;
3972
3973 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3974 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3975
3976 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3977 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3978
3979 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3980 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3981
3982 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3984 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3986 } else {
3988 }
3989}
3990
3991static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3992{
3994 std::string alternateName = "TEmulatedTuple";
3995 alternateName.append( classname + 5 );
3996
3997 std::string fullname = "ROOT::Internal::" + alternateName;
3998 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3999 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4000 return fullname;
4001
4002 {
4003 // Check if we can produce the tuple
4004 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4005 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4006 auto deleter = [](TypeInfo_t *type) {
4007 gInterpreter->TypeInfo_Delete(type);
4008 };
4009 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4010 while (iter != theEnd) {
4011 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4012 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4013 if (!silent)
4014 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4015 classname, iter->c_str());
4016 return "";
4017 }
4018 ++iter;
4019 }
4020 }
4021
4022 std::string guard_name;
4024 std::ostringstream guard;
4025 guard << "ROOT_INTERNAL_TEmulated_";
4026 guard << guard_name;
4027
4028 std::ostringstream alternateTuple;
4029 alternateTuple << "#ifndef " << guard.str() << "\n";
4030 alternateTuple << "#define " << guard.str() << "\n";
4031 alternateTuple << "namespace ROOT { namespace Internal {\n";
4032 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4033 alternateTuple << "template <> struct " << alternateName << " {\n";
4034
4035 // This could also be a compile time choice ...
4036 switch(IsTupleAscending()) {
4038 unsigned int nMember = 0;
4039 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4040 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4041 while (iter != theEnd) {
4042 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4043 ++iter;
4044 ++nMember;
4045 }
4046 break;
4047 }
4049 unsigned int nMember = tupleContent.fElements.size() - 3;
4050 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4051 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4052 while (iter != theEnd) {
4053 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4054 ++iter;
4055 --nMember;
4056 }
4057 break;
4058 }
4060 Fatal("TCling::SetClassInfo::AlternateTuple",
4061 "Layout of std::tuple on this platform is unexpected.");
4062 break;
4063 }
4064 }
4065
4066 alternateTuple << "};\n";
4067 alternateTuple << "}}\n";
4068 alternateTuple << "#endif\n";
4069 if (!gCling->Declare(alternateTuple.str().c_str()))
4070 {
4071 // Declare is not silent (yet?), so add an explicit error message
4072 // to indicate the consequence of the syntax errors.
4073 Error("Load","Could not declare %s",alternateName.c_str());
4074 return "";
4075 }
4076 alternateName = "ROOT::Internal::" + alternateName;
4077 return alternateName;
4078}
4079
4080////////////////////////////////////////////////////////////////////////////////
4081/// Set pointer to the TClingClassInfo in TClass.
4082/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4083/// already have one.
4084
4086{
4087 // We are shutting down, there is no point in reloading, it only triggers
4088 // redundant deserializations.
4089 if (fIsShuttingDown) {
4090 // Remove the decl_id from the DeclIdToTClass map
4091 if (cl->fClassInfo) {
4094 // Test again as another thread may have set fClassInfo to nullptr.
4095 if (TClinginfo) {
4097 }
4098 delete TClinginfo;
4099 cl->fClassInfo = nullptr;
4100 }
4101 return;
4102 }
4103
4105 if (cl->fClassInfo && !reload) {
4106 return;
4107 }
4108 //Remove the decl_id from the DeclIdToTClass map
4110 if (TClinginfo) {
4112 }
4113 delete TClinginfo;
4114 cl->fClassInfo = nullptr;
4115 std::string name(cl->GetName());
4116
4117 auto SetWithoutClassInfoState = [](TClass *cl)
4118 {
4119 if (cl->fState != TClass::kHasTClassInit) {
4120 if (cl->fStreamerInfo->GetEntries() != 0) {
4122 } else {
4124 }
4125 }
4126 };
4127 // Handle the special case of 'tuple' where we ignore the real implementation
4128 // details and just overlay a 'simpler'/'simplistic' version that is easy
4129 // for the I/O to understand and handle.
4130 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4131 if (!reload)
4132 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4133 if (reload || name.empty()) {
4134 // We could not generate the alternate
4136 return;
4137 }
4138 }
4139
4141 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4142 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4143 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4144 // TClingClassInfoReadOnly.
4146 if (!info->IsValid()) {
4148 delete info;
4149 return;
4150 }
4151 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4152 // In case a class contains an external enum, the enum will be seen as a
4153 // class. We must detect this special case and make the class a Zombie.
4154 // Here we assume that a class has at least one method.
4155 // We can NOT call TClass::Property from here, because this method
4156 // assumes that the TClass is well formed to do a lot of information
4157 // caching. The method SetClassInfo (i.e. here) is usually called during
4158 // the building phase of the TClass, hence it is NOT well formed yet.
4160 if (
4161 info->IsValid() &&
4162 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4163 ) {
4165 }
4166 if (!info->IsLoaded()) {
4167 if (info->Property() & (kIsNamespace)) {
4168 // Namespaces can have info but no corresponding CINT dictionary
4169 // because they are auto-created if one of their contained
4170 // classes has a dictionary.
4172 }
4173 // this happens when no dictionary is available
4174 delete info;
4175 cl->fClassInfo = nullptr;
4176 }
4177 if (zombieCandidate && !cl->GetCollectionType()) {
4178 cl->MakeZombie();
4179 }
4180 // If we reach here, the info was valid (See early returns).
4181 if (cl->fState != TClass::kHasTClassInit) {
4182 if (cl->fClassInfo) {
4184 } else {
4185// if (TClassEdit::IsSTLCont(cl->GetName()) {
4186// There will be an emulated collection proxy, is that the same?
4187// cl->fState = TClass::kEmulated;
4188// } else {
4189 if (cl->fStreamerInfo->GetEntries() != 0) {
4191 } else {
4193 }
4194// }
4195 }
4196 }
4197 if (cl->fClassInfo) {
4198 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4199 }
4200}
4201
4202////////////////////////////////////////////////////////////////////////////////
4203/// Checks if an entity with the specified name is defined in Cling.
4204/// Returns kUnknown if the entity is not defined.
4205/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4206/// Returns kKnown if the entity is defined.
4207///
4208/// By default, structs, namespaces, classes, enums and unions are looked for.
4209/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4210/// namespaces only are considered. I.e. if the name is an enum or a union,
4211/// the returned value is false.
4212///
4213/// In the case where the class is not loaded and belongs to a namespace
4214/// or is nested, looking for the full class name is outputting a lots of
4215/// (expected) error messages. Currently the only way to avoid this is to
4216/// specifically check that each level of nesting is already loaded.
4217/// In case of templates the idea is that everything between the outer
4218/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4219
4222{
4224 static const char *anonEnum = "anonymous enum ";
4225 static const int cmplen = strlen(anonEnum);
4226
4227 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4228 return kUnknown;
4229 }
4230
4231 // Do not turn on the AutoLoading if it is globally off.
4233
4234 // Avoid the double search below in case the name is a fundamental type
4235 // or typedef to a fundamental type.
4236 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4237 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4238
4240 && fundType->GetType() > 0) {
4241 // Fundamental type, no a class.
4242 return kUnknown;
4243 }
4244
4245 // Migrated from within TClass::GetClass
4246 // If we want to know if a class or a namespace with this name exists in the
4247 // interpreter and this is an enum in the type system, before or after loading
4248 // according to the autoload function argument, return kUnknown.
4250 return kUnknown;
4251
4252 const char *classname = name;
4253
4254 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4256 int fStoreAutoLoad = 0;
4257 int fStoreAutoParse = 0;
4258 bool fSuspendedAutoParse = false;
4259 public:
4261 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4262 }
4263
4264 void SuspendAutoParsing() {
4265 fSuspendedAutoParse = true;
4266 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4267 }
4268
4271 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4272 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4273 }
4274 };
4275
4277 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4278 autoLoadParseRAII.SuspendAutoParsing();
4279
4280 // First we want to check whether the decl exist, but _without_
4281 // generating any template instantiation. However, the lookup
4282 // still will create a forward declaration of the class template instance
4283 // if it exist. In this case, the return value of findScope will still
4284 // be zero but the type will be initialized.
4285 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4286 // this forward declaration.
4287 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4288 const clang::Type *type = nullptr;
4289 const clang::Decl *decl
4290 = lh.findScope(classname,
4291 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4292 : cling::LookupHelper::NoDiagnostics,
4293 &type, /* intantiateTemplate= */ false );
4294 if (!decl) {
4295 std::string buf = TClassEdit::InsertStd(classname);
4296 decl = lh.findScope(buf,
4297 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4298 : cling::LookupHelper::NoDiagnostics,
4299 &type,false);
4300 }
4301
4302 if (type) {
4303 // If decl==0 and the type is valid, then we have a forward declaration.
4304 if (!decl) {
4305 // If we have a forward declaration for a class template instantiation,
4306 // we want to ignore it if it was produced/induced by the call to
4307 // findScope, however we can not distinguish those from the
4308 // instantiation induce by 'soft' use (and thus also induce by the
4309 // same underlying code paths)
4310 // ['soft' use = use not requiring a complete definition]
4311 // So to reduce the amount of disruption to the existing code we
4312 // would just ignore those for STL collection, for which we really
4313 // need to have the compiled collection proxy (and thus the TClass
4314 // bootstrap).
4315 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4316 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4317 (type->getAsCXXRecordDecl());
4318 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4319 // Since the point of instantiation is invalid, we 'guess' that
4320 // the 'instantiation' of the forwarded type appended in
4321 // findscope.
4323 // For STL Collection we return kUnknown.
4324 return kUnknown;
4325 }
4326 }
4327 }
4329 if (!tci.IsValid()) {
4330 return kUnknown;
4331 }
4334
4335 if (tci.Property() & propertiesMask) {
4336 bool hasClassDefInline = false;
4338 // We do not need to check for ClassDefInline when this is called from
4339 // TClass::Init, we only do it for the call from TClass::GetClass.
4340 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4341 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4342
4343 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4344 int lineNumber = 0;
4345 bool success = false;
4346 std::tie(success, lineNumber) =
4349 }
4350 }
4351
4352 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4353 // , hasClassDefInline);
4354
4355 // We are now sure that the entry is not in fact an autoload entry.
4357 return kWithClassDefInline;
4358 else
4359 return kKnown;
4360 } else {
4361 // We are now sure that the entry is not in fact an autoload entry.
4362 return kUnknown;
4363 }
4364 }
4365
4366 if (decl)
4367 return kKnown;
4368 else
4369 return kUnknown;
4370
4371 // Setting up iterator part of TClingTypedefInfo is too slow.
4372 // Copy the lookup code instead:
4373 /*
4374 TClingTypedefInfo t(fInterpreter, name);
4375 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4376 delete[] classname;
4377 return kTRUE;
4378 }
4379 */
4380
4381// const clang::Decl *decl = lh.findScope(name);
4382// if (!decl) {
4383// std::string buf = TClassEdit::InsertStd(name);
4384// decl = lh.findScope(buf);
4385// }
4386
4387// return (decl);
4388}
4389
4390////////////////////////////////////////////////////////////////////////////////
4391/// Return true if there is a class template by the given name ...
4392
4394{
4395 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4396 // Interpreter transaction ahead, needs locking
4398 const clang::Decl *decl
4399 = lh.findClassTemplate(name,
4400 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4401 : cling::LookupHelper::NoDiagnostics);
4402 if (!decl) {
4403 std::string strname = "std::";
4404 strname += name;
4405 decl = lh.findClassTemplate(strname,
4406 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4407 : cling::LookupHelper::NoDiagnostics);
4408 }
4409 return nullptr != decl;
4410}
4411
4412////////////////////////////////////////////////////////////////////////////////
4413/// Create list of pointers to base class(es) for TClass cl.
4414
4416{
4418 if (cl->fBase) {
4419 return;
4420 }
4422 if (!tci) return;
4424 TList *listOfBase = new TList;
4425 while (t.Next()) {
4426 // if name cannot be obtained no use to put in list
4427 if (t.IsValid() && t.Name()) {
4429 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4430 }
4431 }
4432 // Now that is complete, publish it.
4433 cl->fBase = listOfBase;
4434}
4435
4436////////////////////////////////////////////////////////////////////////////////
4437/// Create list of pointers to enums for TClass cl.
4438
4440{
4442
4443 const Decl * D;
4444 TClass* cl = enumList.GetClass();
4445 if (cl) {
4446 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4447 }
4448 else {
4449 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4450 }
4451 // Iterate on the decl of the class and get the enums.
4452 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4453 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4454 // Collect all contexts of the namespace.
4455 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4456 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4458 declIter != declEnd; ++declIter) {
4459 // Iterate on all decls for each context.
4460 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4461 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4462 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4463 // Get name of the enum type.
4464 std::string buf;
4465 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4466 llvm::raw_string_ostream stream(buf);
4467 // Don't trigger fopen of the source file to count lines:
4468 Policy.AnonymousTagLocations = false;
4469 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4470 stream.flush();
4471 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4472 if (!buf.empty()) {
4473 const char* name = buf.c_str();
4474 // Add the enum to the list of loaded enums.
4475 enumList.Get(ED, name);
4476 }
4477 }
4478 }
4479 }
4480 }
4481}
4482
4483////////////////////////////////////////////////////////////////////////////////
4484/// Create list of pointers to function templates for TClass cl.
4485
4487{
4489
4490 const Decl * D;
4492 if (cl) {
4493 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4495 }
4496 else {
4497 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4498 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4499 }
4500 // Iterate on the decl of the class and get the enums.
4501 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4502 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4503 // Collect all contexts of the namespace.
4504 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4505 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4508 // Iterate on all decls for each context.
4509 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4510 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4511 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4512 funcTempList->Get(FTD);
4513 }
4514 }
4515 }
4516 }
4517}
4518
4519////////////////////////////////////////////////////////////////////////////////
4520/// Get the scopes representing using declarations of namespace
4521
4522std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4523{
4525 return ci->GetUsingNamespaces();
4526}
4527
4528////////////////////////////////////////////////////////////////////////////////
4529/// Create list of pointers to data members for TClass cl.
4530/// This is now a nop. The creation and updating is handled in
4531/// TListOfDataMembers.
4532
4534{
4535}
4536
4537////////////////////////////////////////////////////////////////////////////////
4538/// Create list of pointers to methods for TClass cl.
4539/// This is now a nop. The creation and updating is handled in
4540/// TListOfFunctions.
4541
4543{
4544}
4545
4546////////////////////////////////////////////////////////////////////////////////
4547/// Update the list of pointers to method for TClass cl
4548/// This is now a nop. The creation and updating is handled in
4549/// TListOfFunctions.
4550
4552{
4553}
4554
4555////////////////////////////////////////////////////////////////////////////////
4556/// Update the list of pointers to data members for TClass cl
4557/// This is now a nop. The creation and updating is handled in
4558/// TListOfDataMembers.
4559
4561{
4562}
4563
4564////////////////////////////////////////////////////////////////////////////////
4565/// Create list of pointers to method arguments for TMethod m.
4566
4568{
4570 if (m->fMethodArgs) {
4571 return;
4572 }
4573 TList *arglist = new TList;
4575 while (t.Next()) {
4576 if (t.IsValid()) {
4578 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4579 }
4580 }
4581 m->fMethodArgs = arglist;
4582}
4583
4584////////////////////////////////////////////////////////////////////////////////
4585/// Return whether we are waiting for more input either because the collected
4586/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4587
4589{
4590 return fMetaProcessor->awaitingMoreInput();
4591}
4592
4593////////////////////////////////////////////////////////////////////////////////
4594/// Generate a TClass for the given class.
4595/// Since the caller has already check the ClassInfo, let it give use the
4596/// result (via the value of emulation) rather than recalculate it.
4597
4598TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4599{
4600// For now the following line would lead to the (unwanted) instantiation
4601// of class template. This could/would need to be resurrected only if
4602// we re-introduce so sort of automatic instantiation. However this would
4603// have to include carefull look at the template parameter to avoid
4604// creating instance we can not really use (if the parameter are only forward
4605// declaration or do not have all the necessary interfaces).
4606
4607 // TClingClassInfo tci(fInterpreter, classname);
4608 // if (1 || !tci.IsValid()) {
4609
4610 Version_t version = 1;
4611 if (TClassEdit::IsSTLCont(classname)) {
4612 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4613 }
4615 TClass *cl = new TClass(classname, version, silent);
4616 if (!emulation) {
4617 // Set the class version if the class is versioned.
4618 // Note that we cannot just call CLASS::Class_Version() as we might not have
4619 // an execution engine (when invoked from rootcling).
4620
4621 // Do not call cl->GetClassVersion(), it has side effects!
4623 if (oldvers == version && cl->GetClassInfo()) {
4624 // We have a version and it might need an update.
4626 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4627 // Namespaces don't have class versions.
4628 return cl;
4629 }
4630 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4633 if (!mi.IsValid()) {
4634 if (cl->TestBit(TClass::kIsTObject)) {
4635 Error("GenerateTClass",
4636 "Cannot find %s::Class_Version()! Class version might be wrong.",
4637 cl->GetName());
4638 }
4639 return cl;
4640 }
4641 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4642 *fInterpreter);
4643 if (newvers == -1) {
4644 // Didn't manage to determine the class version from the AST.
4645 // Use runtime instead.
4646 if ((mi.Property() & kIsStatic)
4647 && !fInterpreter->isInSyntaxOnlyMode()) {
4648 // This better be a static function.
4650 callfunc.SetFunc(&mi);
4651 newvers = callfunc.ExecInt(nullptr);
4652 } else {
4653 Error("GenerateTClass",
4654 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4655 cl->GetName());
4656 }
4657 }
4658 if (newvers != oldvers) {
4659 cl->fClassVersion = newvers;
4660 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4661 }
4662 }
4663 }
4664
4665 return cl;
4666
4667// } else {
4668// return GenerateTClass(&tci,silent);
4669// }
4670}
4671
4672#if 0
4673////////////////////////////////////////////////////////////////////////////////
4674
4676{
4677 includes += info->FileName();
4678
4679 const clang::ClassTemplateSpecializationDecl *templateCl
4680 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4681 if (templateCl) {
4682 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4683 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4684 if (arg.getKind() == clang::TemplateArgument::Type) {
4685 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4686
4687 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4688 // We really need a header file.
4689 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4690 if (argdecl) {
4691 includes += ";";
4692 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4694 } else {
4695 std::string Result;
4696 llvm::raw_string_ostream OS(Result);
4697 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4698 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4699 }
4700 }
4701 }
4702 }
4703 }
4704}
4705#endif
4706
4707////////////////////////////////////////////////////////////////////////////////
4708/// Generate a TClass for the given class.
4709
4711{
4713 if (!info || !info->IsValid()) {
4714 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4715 return nullptr;
4716 }
4717 // We are in the case where we have AST nodes for this class.
4718 TClass *cl = nullptr;
4719 std::string classname;
4720 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4721 if (TClassEdit::IsSTLCont(classname)) {
4722#if 0
4723 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4724 // We need to build up the list of required headers, by
4725 // looking at each template arguments.
4728
4729 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4730 // 0 means success.
4731 cl = TClass::LoadClass(classnam.c_str(), silent);
4732 if (cl == 0) {
4733 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4734 }
4735 }
4736#endif
4737 if (cl == nullptr) {
4738 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4739 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4740 }
4741 } else {
4742 // For regular class, just create a TClass on the fly ...
4743 // Not quite useful yet, but that what CINT used to do anyway.
4744 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4745 }
4746 // Add the new TClass to the map of declid and TClass*.
4747 if (cl) {
4749 }
4750 return cl;
4751}
4752
4753////////////////////////////////////////////////////////////////////////////////
4754/// Generate the dictionary for the C++ classes listed in the first
4755/// argument (in a semi-colon separated list).
4756/// 'includes' contains a semi-colon separated list of file to
4757/// `#include` in the dictionary.
4758/// For example:
4759/// ~~~ {.cpp}
4760/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4761/// ~~~
4762/// or
4763/// ~~~ {.cpp}
4764/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4765/// ~~~
4766
4767Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4768{
4769 if (classes == nullptr || classes[0] == 0) {
4770 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4771 return 0;
4772 }
4773 // Split the input list
4774 std::vector<std::string> listClasses;
4775 for (
4776 const char* current = classes, *prev = classes;
4777 *current != 0;
4778 ++current
4779 ) {
4780 if (*current == ';') {
4781 listClasses.push_back(std::string(prev, current - prev));
4782 prev = current + 1;
4783 }
4784 else if (*(current + 1) == 0) {
4785 listClasses.push_back(std::string(prev, current + 1 - prev));
4786 prev = current + 1;
4787 }
4788 }
4789 std::vector<std::string> listIncludes;
4790 if (!includes)
4791 includes = "";
4792 for (
4793 const char* current = includes, *prev = includes;
4794 *current != 0;
4795 ++current
4796 ) {
4797 if (*current == ';') {
4798 listIncludes.push_back(std::string(prev, current - prev));
4799 prev = current + 1;
4800 }
4801 else if (*(current + 1) == 0) {
4802 listIncludes.push_back(std::string(prev, current + 1 - prev));
4803 prev = current + 1;
4804 }
4805 }
4806 // Generate the temporary dictionary file
4808 std::vector<std::string>(), std::vector<std::string>());
4809}
4810
4811////////////////////////////////////////////////////////////////////////////////
4812/// Return pointer to cling Decl of global/static variable that is located
4813/// at the address given by addr.
4814
4816{
4818 DeclId_t d;
4820
4821 // Could trigger deserialization of decls.
4822 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4823
4824 if (cl) {
4825 d = cl->GetDataMember(name);
4826 // We check if the decl of the data member has an annotation which indicates
4827 // an ioname.
4828 // In case this is true, if the name requested is not the ioname, we
4829 // return 0, as if the member did not exist. In some sense we override
4830 // the information in the TClassInfo instance, isolating the typesystem in
4831 // TClass from the one in the AST.
4832 if (const ValueDecl* decl = (const ValueDecl*) d){
4833 std::string ioName;
4835 if (hasIoName && ioName != name) return nullptr;
4836 }
4837 return d;
4838 }
4839 // We are looking up for something on the TU scope.
4840 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4841 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4842 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4843 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4844 // are only fulfilling ROOT's understanding for a Data Member.
4845 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4846 // similar as below.
4847 using namespace clang;
4848 Sema& SemaR = fInterpreter->getSema();
4849 DeclarationName DName = &SemaR.Context.Idents.get(name);
4850
4851 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4852 Sema::ForExternalRedeclaration);
4853
4854 cling::utils::Lookup::Named(&SemaR, R);
4855
4856 LookupResult::Filter F = R.makeFilter();
4857 // Filter the data-member looking decls.
4858 while (F.hasNext()) {
4859 NamedDecl *D = F.next();
4862 continue;
4863 F.erase();
4864 }
4865 F.done();
4866
4867 if (R.isSingleResult())
4868 return R.getFoundDecl();
4869 return nullptr;
4870}
4871
4872////////////////////////////////////////////////////////////////////////////////
4873/// Return pointer to cling Decl of global/static variable that is located
4874/// at the address given by addr.
4875
4877{
4879
4880 const clang::Decl* possibleEnum = nullptr;
4881 // FInd the context of the decl.
4882 if (cl) {
4884 if (cci) {
4885 const clang::DeclContext* dc = nullptr;
4886 if (const clang::Decl* D = cci->GetDecl()) {
4887 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4889 }
4890 }
4891 if (dc) {
4892 // If it is a data member enum.
4893 // Could trigger deserialization of decls.
4894 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4895 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4896 } else {
4897 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4898 }
4899 }
4900 } else {
4901 // If it is a global enum.
4902 // Could trigger deserialization of decls.
4903 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4904 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4905 }
4906 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4908 return possibleEnum;
4909 }
4910 return nullptr;
4911}
4912
4913////////////////////////////////////////////////////////////////////////////////
4914/// Return pointer to cling DeclId for a global value
4915
4916TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4917{
4918 if (!gv) return nullptr;
4919
4920 llvm::StringRef mangled_name = gv->getName();
4921
4922 int err = 0;
4923 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4924 if (err) {
4925 if (err == -2) {
4926 // It might simply be an unmangled global name.
4927 DeclId_t d;
4929 d = gcl.GetDataMember(mangled_name.str().c_str());
4930 return d;
4931 }
4932 return nullptr;
4933 }
4934
4935 std::string scopename(demangled_name_c);
4937
4938 //
4939 // Separate out the class or namespace part of the
4940 // function name.
4941 //
4942 std::string dataname;
4943
4944 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4945 scopename.erase(0, sizeof("typeinfo for ")-1);
4946 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4947 scopename.erase(0, sizeof("vtable for ")-1);
4948 } else {
4949 // See if it is a function
4950 std::string::size_type pos = scopename.rfind('(');
4951 if (pos != std::string::npos) {
4952 return nullptr;
4953 }
4954 // Separate the scope and member name
4955 pos = scopename.rfind(':');
4956 if (pos != std::string::npos) {
4957 if ((pos != 0) && (scopename[pos-1] == ':')) {
4958 dataname = scopename.substr(pos+1);
4959 scopename.erase(pos-1);
4960 }
4961 } else {
4962 scopename.clear();
4964 }
4965 }
4966 //fprintf(stderr, "name: '%s'\n", name.c_str());
4967 // Now we have the class or namespace name, so do the lookup.
4968
4969
4970 DeclId_t d;
4971 if (scopename.size()) {
4973 d = cl.GetDataMember(dataname.c_str());
4974 }
4975 else {
4977 d = gcl.GetDataMember(dataname.c_str());
4978 }
4979 return d;
4980}
4981
4982////////////////////////////////////////////////////////////////////////////////
4983/// NOT IMPLEMENTED.
4984
4986{
4987 Error("GetDataMemberWithValue()", "not implemented");
4988 return nullptr;
4989}
4990
4991////////////////////////////////////////////////////////////////////////////////
4992/// Return pointer to cling DeclId for a data member with a given name.
4993
4995{
4996 // NOT IMPLEMENTED.
4997 Error("GetDataMemberAtAddr()", "not implemented");
4998 return nullptr;
4999}
5000
5001////////////////////////////////////////////////////////////////////////////////
5002/// Return the cling mangled name for a method of a class with parameters
5003/// params (params is a string of actual arguments, not formal ones). If the
5004/// class is 0 the global function list will be searched.
5005
5007 const char* params, Bool_t objectIsConst /* = kFALSE */)
5008{
5011 if (cl) {
5014 &offset);
5015 }
5016 else {
5019 func.SetFunc(&gcl, method, params, &offset);
5020 }
5022 if (!mi) return "";
5023 TString mangled_name( mi->GetMangledName() );
5024 delete mi;
5025 return mangled_name;
5026}
5027
5028////////////////////////////////////////////////////////////////////////////////
5029/// Return the cling mangled name for a method of a class with a certain
5030/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5031/// list will be searched.
5032
5034 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5035 EFunctionMatchMode mode /* = kConversionMatch */)
5036{
5038 if (cl) {
5039 return ((TClingClassInfo*)cl->GetClassInfo())->
5040 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5041 }
5043 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5044}
5045
5046////////////////////////////////////////////////////////////////////////////////
5047/// Return pointer to cling interface function for a method of a class with
5048/// parameters params (params is a string of actual arguments, not formal
5049/// ones). If the class is 0 the global function list will be searched.
5050
5052 const char* params, Bool_t objectIsConst /* = kFALSE */)
5053{
5056 if (cl) {
5059 &offset);
5060 }
5061 else {
5064 func.SetFunc(&gcl, method, params, &offset);
5065 }
5066 return (void*) func.InterfaceMethod();
5067}
5068
5069////////////////////////////////////////////////////////////////////////////////
5070/// Return pointer to cling interface function for a method of a class with
5071/// a certain name.
5072
5074{
5076 DeclId_t f;
5078 if (cl) {
5079 f = cl->GetMethod(method).GetDeclId();
5080 }
5081 else {
5083 f = gcl.GetMethod(method).GetDeclId();
5084 }
5085 return f;
5086
5087}
5088
5089////////////////////////////////////////////////////////////////////////////////
5090/// Insert overloads of name in cl to res.
5091
5093 std::vector<DeclId_t>& res) const
5094{
5095 clang::Sema& S = fInterpreter->getSema();
5096 clang::ASTContext& Ctx = S.Context;
5097 const clang::Decl* CtxDecl
5098 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5099 Ctx.getTranslationUnitDecl();
5100 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5101 const clang::DeclContext* DeclCtx = RecDecl;
5102
5103 if (!DeclCtx)
5105 if (!DeclCtx) return;
5106
5107 clang::DeclarationName DName;
5108 // The DeclarationName is funcname, unless it's a ctor or dtor.
5109 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5110
5111 if (RecDecl) {
5112 if (RecDecl->getNameAsString() == funcname) {
5113 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5114 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5115 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5116 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5117 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5118 } else {
5119 DName = &Ctx.Idents.get(funcname);
5120 }
5121 } else {
5122 DName = &Ctx.Idents.get(funcname);
5123 }
5124
5125 // NotForRedeclaration: we want to find names in inline namespaces etc.
5126 clang::LookupResult R(S, DName, clang::SourceLocation(),
5127 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5128 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5129 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5130 if (R.empty()) return;
5131 R.resolveKind();
5132 res.reserve(res.size() + (R.end() - R.begin()));
5133 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5134 IR != ER; ++IR) {
5135 if (const clang::FunctionDecl* FD
5136 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5137 if (!FD->getDescribedFunctionTemplate()) {
5138 res.push_back(FD);
5139 }
5140 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5141 // FIXME: multi-level using
5142 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5143 res.push_back(USD);
5144 }
5145 }
5146 }
5147}
5148
5149////////////////////////////////////////////////////////////////////////////////
5150/// Return pointer to cling interface function for a method of a class with
5151/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5152/// function list will be searched.
5153
5155 const char* proto,
5156 Bool_t objectIsConst /* = kFALSE */,
5157 EFunctionMatchMode mode /* = kConversionMatch */)
5158{
5160 void* f;
5161 if (cl) {
5162 f = ((TClingClassInfo*)cl->GetClassInfo())->
5163 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5164 }
5165 else {
5167 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5168 }
5169 return f;
5170}
5171
5172////////////////////////////////////////////////////////////////////////////////
5173/// Return pointer to cling DeclId for a method of a class with
5174/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5175/// function list will be searched.
5176
5178 const char* params,
5179 Bool_t objectIsConst /* = kFALSE */)
5180{
5182 DeclId_t f;
5184 if (cl) {
5185 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5186 }
5187 else {
5189 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5190 }
5191 return f;
5192}
5193
5194////////////////////////////////////////////////////////////////////////////////
5195/// Return pointer to cling interface function for a method of a class with
5196/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5197/// function list will be searched.
5198
5200 const char* proto,
5201 Bool_t objectIsConst /* = kFALSE */,
5202 EFunctionMatchMode mode /* = kConversionMatch */)
5203{
5205 DeclId_t f;
5207 if (cl) {
5208 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5209 }
5210 else {
5212 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5213 }
5214 return f;
5215}
5216
5217////////////////////////////////////////////////////////////////////////////////
5218/// Return pointer to cling interface function for a method of a class with
5219/// a certain name.
5220
5222{
5224 DeclId_t f;
5226 if (cl) {
5227 f = cl->GetFunctionTemplate(name);
5228 }
5229 else {
5231 f = gcl.GetFunctionTemplate(name);
5232 }
5233 return f;
5234
5235}
5236
5237////////////////////////////////////////////////////////////////////////////////
5238/// The 'name' is known to the interpreter, this function returns
5239/// the internal version of this name (usually just resolving typedefs)
5240/// This is used in particular to synchronize between the name used
5241/// by rootcling and by the run-time environment (TClass)
5242/// Return 0 if the name is not known.
5243
5244void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5245{
5246 output.clear();
5247
5249
5251 if (!cl.IsValid()) {
5252 return ;
5253 }
5254 if (full) {
5256 return;
5257 }
5258 // Well well well, for backward compatibility we need to act a bit too
5259 // much like CINT.
5262
5263 return;
5264}
5265
5266////////////////////////////////////////////////////////////////////////////////
5267/// Execute a global function with arguments params.
5268///
5269/// FIXME: The cint-based version of this code does not check if the
5270/// SetFunc() call works, and does not do any real checking
5271/// for errors from the Exec() call. It did fetch the most
5272/// recent cint security error and return that in error, but
5273/// this does not really translate well to cling/clang. We
5274/// should enhance these interfaces so that we can report
5275/// compilation and runtime errors properly.
5276
5277void TCling::Execute(const char* function, const char* params, int* error)
5278{
5280 if (error) {
5281 *error = TInterpreter::kNoError;
5282 }
5284 Longptr_t offset = 0L;
5286 func.SetFunc(&cl, function, params, &offset);
5287 func.Exec(nullptr);
5288}
5289
5290////////////////////////////////////////////////////////////////////////////////
5291/// Execute a method from class cl with arguments params.
5292///
5293/// FIXME: The cint-based version of this code does not check if the
5294/// SetFunc() call works, and does not do any real checking
5295/// for errors from the Exec() call. It did fetch the most
5296/// recent cint security error and return that in error, but
5297/// this does not really translate well to cling/clang. We
5298/// should enhance these interfaces so that we can report
5299/// compilation and runtime errors properly.
5300
5301void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5302 const char* params, Bool_t objectIsConst, int* error)
5303{
5305 if (error) {
5306 *error = TInterpreter::kNoError;
5307 }
5308 // If the actual class of this object inherits 2nd (or more) from TObject,
5309 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5310 // hence gInterpreter->Execute will improperly correct the offset.
5311 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5312 Longptr_t offset = 0L;
5315 void* address = (void*)((Longptr_t)addr + offset);
5316 func.Exec(address);
5317}
5318
5319////////////////////////////////////////////////////////////////////////////////
5320
5321void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5322 const char* params, int* error)
5323{
5324 Execute(obj,cl,method,params,false,error);
5325}
5326
5327////////////////////////////////////////////////////////////////////////////////
5328/// Execute a method from class cl with the arguments in array params
5329/// (params[0] ... params[n] = array of TObjString parameters).
5330/// Convert the TObjArray array of TObjString parameters to a character
5331/// string of comma separated parameters.
5332/// The parameters of type 'char' are enclosed in double quotes and all
5333/// internal quotes are escaped.
5334
5336 TObjArray* params, int* error)
5337{
5338 if (!method) {
5339 Error("Execute", "No method was defined");
5340 return;
5341 }
5342 TList* argList = method->GetListOfMethodArgs();
5343 // Check number of actual parameters against of expected formal ones
5344
5345 Int_t nparms = argList->LastIndex() + 1;
5346 Int_t argc = params ? params->GetEntries() : 0;
5347
5348 if (argc > nparms) {
5349 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5350 return;
5351 }
5352 if (nparms != argc) {
5353 // Let's see if the 'missing' argument are all defaulted.
5354 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5355 assert(nparms > 0);
5356
5357 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5358 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5359 // There is a default value for the first missing
5360 // argument, so we are fine.
5361 } else {
5362 Int_t firstDefault = -1;
5363 for (Int_t i = 0; i < nparms; i ++) {
5364 arg = (TMethodArg *) argList->At( i );
5365 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5366 firstDefault = i;
5367 break;
5368 }
5369 }
5370 if (firstDefault >= 0) {
5371 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);
5372 } else {
5373 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5374 }
5375 return;
5376 }
5377 }
5378
5379 const char* listpar = "";
5380 TString complete(10);
5381 if (params) {
5382 // Create a character string of parameters from TObjArray
5383 TIter next(params);
5384 for (Int_t i = 0; i < argc; i ++) {
5385 TMethodArg* arg = (TMethodArg*) argList->At(i);
5387 TObjString* nxtpar = (TObjString*) next();
5388 if (i) {
5389 complete += ',';
5390 }
5391 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5392 TString chpar('\"');
5393 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5394 // At this point we have to check if string contains \\"
5395 // and apply some more sophisticated parser. Not implemented yet!
5396 complete += chpar;
5397 complete += '\"';
5398 }
5399 else {
5400 complete += nxtpar->String();
5401 }
5402 }
5403 listpar = complete.Data();
5404 }
5405
5406 // And now execute it.
5408 if (error) {
5409 *error = TInterpreter::kNoError;
5410 }
5411 // If the actual class of this object inherits 2nd (or more) from TObject,
5412 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5413 // hence gInterpreter->Execute will improperly correct the offset.
5414 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5417 func.Init(*minfo);
5418 func.SetArgs(listpar);
5419 // Now calculate the 'this' pointer offset for the method
5420 // when starting from the class described by cl.
5421 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5422 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5423 void* address = (void*)((Longptr_t)addr + offset);
5424 func.Exec(address);
5425}
5426
5427////////////////////////////////////////////////////////////////////////////////
5428
5430 const void* args[] /*=0*/,
5431 int nargs /*=0*/,
5432 void* ret/*= 0*/) const
5433{
5434 if (!method) {
5435 Error("ExecuteWithArgsAndReturn", "No method was defined");
5436 return;
5437 }
5438
5440 TClingCallFunc func(*minfo);
5441 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5442}
5443
5444////////////////////////////////////////////////////////////////////////////////
5445/// Execute a cling macro.
5446
5448{
5450 fCurExecutingMacros.push_back(filename);
5452 fCurExecutingMacros.pop_back();
5453 return result;
5454}
5455
5456////////////////////////////////////////////////////////////////////////////////
5457/// Return the file name of the current un-included interpreted file.
5458/// See the documentation for GetCurrentMacroName().
5459
5461{
5462 Warning("GetTopLevelMacroName", "Must change return type!");
5463 return fCurExecutingMacros.back();
5464}
5465
5466////////////////////////////////////////////////////////////////////////////////
5467/// Return the file name of the currently interpreted file,
5468/// included or not. Example to illustrate the difference between
5469/// GetCurrentMacroName() and GetTopLevelMacroName():
5470/// ~~~ {.cpp}
5471/// void inclfile() {
5472/// std::cout << "In inclfile.C" << std::endl;
5473/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5474/// TCling::GetCurrentMacroName() << std::endl;
5475/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5476/// TCling::GetTopLevelMacroName() << std::endl;
5477/// }
5478/// ~~~
5479/// ~~~ {.cpp}
5480/// void mymacro() {
5481/// std::cout << "In mymacro.C" << std::endl;
5482/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5483/// TCling::GetCurrentMacroName() << std::endl;
5484/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5485/// TCling::GetTopLevelMacroName() << std::endl;
5486/// std::cout << " Now calling inclfile..." << std::endl;
5487/// gInterpreter->ProcessLine(".x inclfile.C");
5488/// }
5489/// ~~~
5490/// Running mymacro.C will print:
5491///
5492/// ~~~ {.cpp}
5493/// root [0] .x mymacro.C
5494/// ~~~
5495/// In mymacro.C
5496/// ~~~ {.cpp}
5497/// TCling::GetCurrentMacroName() returns ./mymacro.C
5498/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5499/// ~~~
5500/// Now calling inclfile...
5501/// In inclfile.h
5502/// ~~~ {.cpp}
5503/// TCling::GetCurrentMacroName() returns inclfile.C
5504/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5505/// ~~~
5506
5508{
5509#if defined(R__MUST_REVISIT)
5510#if R__MUST_REVISIT(6,0)
5511 Warning("GetCurrentMacroName", "Must change return type!");
5512#endif
5513#endif
5514 return fCurExecutingMacros.back();
5515}
5516
5517////////////////////////////////////////////////////////////////////////////////
5518/// Return the absolute type of typeDesc.
5519/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5520/// You need to use the result immediately before it is being overwritten.
5521
5522const char* TCling::TypeName(const char* typeDesc)
5523{
5524 TTHREAD_TLS_DECL(std::string,t);
5525
5526 if (!strstr(typeDesc, "(*)(")) {
5527 const char *s = strchr(typeDesc, ' ');
5528 const char *template_start = strchr(typeDesc, '<');
5529 if (!strcmp(typeDesc, "long long")) {
5530 t = typeDesc;
5531 }
5532 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5533 t = typeDesc;
5534 }
5535 // s is the position of the second 'word' (if any)
5536 // except in the case of templates where there will be a space
5537 // just before any closing '>': eg.
5538 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5539 else if (s && (template_start == nullptr || (s < template_start))) {
5540 t = s + 1;
5541 }
5542 else {
5543 t = typeDesc;
5544 }
5545 }
5546 else {
5547 t = typeDesc;
5548 }
5549 auto l = t.length();
5550 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5551 --l;
5552 t.resize(l);
5553 return t.c_str(); // NOLINT
5554}
5555
5556static bool requiresRootMap(const char* rootmapfile)
5557{
5559
5560 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5561 libName.consume_back(".rootmap");
5562
5563 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5564}
5565
5566////////////////////////////////////////////////////////////////////////////////
5567/// Read and parse a rootmapfile in its new format, and return 0 in case of
5568/// success, -1 if the file has already been read, and -3 in case its format
5569/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5570/// error.
5571
5573{
5574 if (!(rootmapfile && *rootmapfile))
5575 return 0;
5576
5578 return 0; // success
5579
5580 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5581 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5582
5584#ifdef _MSC_VER
5585 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5586#endif
5587 // Add content of a specific rootmap file
5589 return -1;
5590
5591 // Line 1 is `{ decls }`
5592 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5593
5594 std::ifstream file(rootmapfileNoBackslash);
5595 std::string line;
5596 line.reserve(200);
5597 std::string lib_name;
5598 line.reserve(100);
5599 bool newFormat = false;
5600 while (getline(file, line, '\n')) {
5601 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5602 file.close();
5603 return -3; // old format
5604 }
5605 newFormat = true;
5606
5607 if (line.compare(0, 9, "{ decls }") == 0) {
5608 // forward declarations
5609
5610 while (getline(file, line, '\n')) {
5611 if (line[0] == '[')
5612 break;
5613 if (!uniqueString) {
5614 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5615 rootmapfileNoBackslash.c_str());
5616 return -4;
5617 }
5618 if (!lineDirective.empty())
5619 uniqueString->Append(lineDirective);
5620 uniqueString->Append(line + '\n');
5621 }
5622 }
5623 const char firstChar = line[0];
5624 if (firstChar == '[') {
5625 // new section (library)
5626 auto brpos = line.find(']');
5627 if (brpos == string::npos)
5628 continue;
5629 lib_name = line.substr(1, brpos - 1);
5630 // Remove spaces at the beginning and at the end of the library name
5631 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5632 lib_name.erase(0, lib_name.find_first_not_of(' '));
5633 if (gDebug > 3) {
5634 TString lib_nameTstr(lib_name.c_str());
5635 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5636 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5637 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5638 if (wlib) {
5639 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5640 } else {
5641 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5642 }
5643 delete[] wlib;
5644 delete tokens;
5645 }
5646 } else {
5647 auto keyLenIt = keyLenMap.find(firstChar);
5648 if (keyLenIt == keyLenMap.end())
5649 continue;
5650 unsigned int keyLen = keyLenIt->second;
5651 // Do not make a copy, just start after the key
5652 const char *keyname = line.c_str() + keyLen;
5653 if (gDebug > 6)
5654 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5656 if (isThere) {
5657 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5658 if (firstChar == 'n') {
5659 if (gDebug > 3)
5660 Info("ReadRootmapFile",
5661 "While processing %s, namespace %s was found to be associated to %s although it is already "
5662 "associated to %s",
5663 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5664 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5665 lib_name += " ";
5666 lib_name += isThere->GetValue();
5667 fMapfile->SetValue(keyname, lib_name.c_str());
5668 } else if (!TClassEdit::IsSTLCont(keyname)) {
5669 Warning("ReadRootmapFile",
5670 "While processing %s, %s %s was found to be associated to %s although it is already "
5671 "associated to %s",
5672 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5673 isThere->GetValue());
5674 }
5675 } else { // the same key for the same lib
5676 if (gDebug > 3)
5677 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5678 rootmapfile, keyname, lib_name.c_str());
5679 }
5680 } else {
5681 fMapfile->SetValue(keyname, lib_name.c_str());
5682 }
5683 }
5684 }
5685 file.close();
5686 return 0;
5687}
5688
5689////////////////////////////////////////////////////////////////////////////////
5690/// Create a resource table and read the (possibly) three resource files,
5691/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5692/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5693/// can read additional user defined resource files by creating additional TEnv
5694/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5695/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5696/// case the home directory resides on an automounted remote file system
5697/// and one wants to avoid the file system from being mounted.
5698
5700{
5701 assert(requiresRootMap(name) && "We have a module!");
5702
5703 if (!requiresRootMap(name))
5704 return;
5705
5707
5709
5710 TString sname = "system";
5711 sname += name;
5713
5715 if (ret == -3) // old format
5717 delete [] s;
5718 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5720 ret = ReadRootmapFile(s);
5721 if (ret == -3) // old format
5723 delete [] s;
5726 if (ret == -3) // old format
5728 }
5729 } else {
5731 if (ret == -3) // old format
5733 }
5735}
5736
5737
5738namespace {
5739 using namespace clang;
5740
5741 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5742 // This class is to be considered an helper for AutoLoading.
5743 // It is a recursive visitor is used to inspect namespaces and specializations
5744 // coming from forward declarations in rootmaps and to set the external visible
5745 // storage flag for them.
5746 public:
5747 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5748 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5749 // We want to enable the external lookup for this namespace
5750 // because it may shadow the lookup of other names contained
5751 // in that namespace
5752
5753 nsDecl->setHasExternalVisibleStorage();
5754 fNSSet.insert(nsDecl);
5755 return true;
5756 }
5758 // We want to enable the external lookup for this specialization
5759 // because we can provide a definition for it!
5760 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5761 //SpecSet.insert(specDecl);
5762 specDecl->setHasExternalLexicalStorage();
5763
5764 // No need to recurse. On the contrary, recursing is actively harmful:
5765 // NOTE: must not recurse to prevent this visitor from triggering loading from
5766 // the external AST source (i.e. autoloading). This would be triggered right here,
5767 // before autoloading is even set up, as rootmap file parsing happens before that.
5768 // Even if autoloading is off and has no effect, triggering loading from external
5769 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5770 // from subsequent autoloads!
5771 return false;
5772 }
5773 private:
5774 std::unordered_set<const NamespaceDecl*>& fNSSet;
5775 };
5776}
5777
5778////////////////////////////////////////////////////////////////////////////////
5779/// Load map between class and library. If rootmapfile is specified a
5780/// specific rootmap file can be added (typically used by ACLiC).
5781/// In case of error -1 is returned, 0 otherwise.
5782/// The interpreter uses this information to automatically load the shared
5783/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5784
5786{
5788 return 0;
5789
5791
5792 // open the [system].rootmap files
5793 if (!fMapfile) {
5794 fMapfile = new TEnv();
5798 InitRootmapFile(".rootmap");
5799 }
5800
5801 // Prepare a list of all forward declarations for cling
5802 // For some experiments it is easily as big as 500k characters. To be on the
5803 // safe side, we go for 1M.
5804 TUniqueString uniqueString(1048576);
5805
5806 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5807 // A rootmap file must end with the string ".rootmap".
5809 if (ldpath != fRootmapLoadPath) {
5811#ifdef WIN32
5812 TObjArray* paths = ldpath.Tokenize(";");
5813#else
5814 TObjArray* paths = ldpath.Tokenize(":");
5815#endif
5816 TString d;
5817 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5818 d = ((TObjString *)paths->At(i))->GetString();
5819 // check if directory already scanned
5820 Int_t skip = 0;
5821 for (Int_t j = 0; j < i; j++) {
5822 TString pd = ((TObjString *)paths->At(j))->GetString();
5823 if (pd == d) {
5824 skip++;
5825 break;
5826 }
5827 }
5828 if (!skip) {
5829 void* dirp = gSystem->OpenDirectory(d);
5830 if (dirp) {
5831 if (gDebug > 3) {
5832 Info("LoadLibraryMap", "%s", d.Data());
5833 }
5834 const char* f1;
5835 while ((f1 = gSystem->GetDirEntry(dirp))) {
5836 TString f = f1;
5837 if (f.EndsWith(".rootmap")) {
5838 TString p;
5839 p = d + "/" + f;
5841 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5842 if (gDebug > 4) {
5843 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5844 }
5846
5847 if (ret == 0)
5848 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5849 if (ret == -3) {
5850 // old format
5852 fRootmapFiles->Add(new TNamed(f, p));
5853 }
5854 }
5855 // else {
5856 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5857 // fRootmapFiles->FindObject(f)->ls();
5858 // }
5859 }
5860 }
5861 if (f.BeginsWith("rootmap")) {
5862 TString p;
5863 p = d + "/" + f;
5864 FileStat_t stat;
5865 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5866 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5867 }
5868 }
5869 }
5870 }
5872 }
5873 }
5874 delete paths;
5875 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5876 return -1;
5877 }
5878 }
5879 if (rootmapfile && *rootmapfile) {
5881 if (res == 0) {
5882 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5883 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5885 }
5886 else if (res == -3) {
5887 // old format
5892 }
5893 }
5894 TEnvRec* rec;
5895 TIter next(fMapfile->GetTable());
5896 while ((rec = (TEnvRec*) next())) {
5897 TString cls = rec->GetName();
5898 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5899 // get the first lib from the list of lib and dependent libs
5900 TString libs = rec->GetValue();
5901 if (libs == "") {
5902 continue;
5903 }
5904 TString delim(" ");
5905 TObjArray* tokens = libs.Tokenize(delim);
5906 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5907 // convert "@@" to "::", we used "@@" because TEnv
5908 // considers "::" a terminator
5909 cls.Remove(0, 8);
5910 cls.ReplaceAll("@@", "::");
5911 // convert "-" to " ", since class names may have
5912 // blanks and TEnv considers a blank a terminator
5913 cls.ReplaceAll("-", " ");
5914 if (gDebug > 6) {
5915 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5916 if (wlib) {
5917 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5918 }
5919 else {
5920 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5921 }
5922 delete[] wlib;
5923 }
5924 delete tokens;
5925 }
5926 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5927 cls.Remove(0, 8);
5928 // convert "-" to " ", since class names may have
5929 // blanks and TEnv considers a blank a terminator
5930 cls.ReplaceAll("-", " ");
5931 fInterpreter->declare(cls.Data());
5932 }
5933 }
5934
5935 // Process the forward declarations collected
5936 cling::Transaction* T = nullptr;
5937 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5938 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5939
5940 if (compRes!=cling::Interpreter::kSuccess){
5941 Warning("LoadLibraryMap",
5942 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5943 }
5944
5945 if (T) {
5946 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5947 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5948 if (declIt->m_DGR.isSingleDecl()) {
5949 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5950 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5951 evsAdder.TraverseDecl(D);
5952 }
5953 }
5954 }
5955 }
5956 }
5957
5958 // clear duplicates
5959
5960 return 0;
5961}
5962
5963////////////////////////////////////////////////////////////////////////////////
5964/// Scan again along the dynamic path for library maps. Entries for the loaded
5965/// shared libraries are unloaded first. This can be useful after reseting
5966/// the dynamic path through TSystem::SetDynamicPath()
5967/// In case of error -1 is returned, 0 otherwise.
5968
5975
5976////////////////////////////////////////////////////////////////////////////////
5977/// Reload the library map entries coming from all the loaded shared libraries,
5978/// after first unloading the current ones.
5979/// In case of error -1 is returned, 0 otherwise.
5980
5982{
5984 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5985 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5986 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5987 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5990 if (ret < 0) {
5991 continue;
5992 }
5994 if (sharedLibBaseStr.EndsWith(".dll")) {
5995 rootMapBaseStr.ReplaceAll(".dll", "");
5996 }
5997 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5998 rootMapBaseStr.ReplaceAll(".DLL", "");
5999 }
6000 else if (sharedLibBaseStr.EndsWith(".so")) {
6001 rootMapBaseStr.ReplaceAll(".so", "");
6002 }
6003 else if (sharedLibBaseStr.EndsWith(".sl")) {
6004 rootMapBaseStr.ReplaceAll(".sl", "");
6005 }
6006 else if (sharedLibBaseStr.EndsWith(".dl")) {
6007 rootMapBaseStr.ReplaceAll(".dl", "");
6008 }
6009 else if (sharedLibBaseStr.EndsWith(".a")) {
6010 rootMapBaseStr.ReplaceAll(".a", "");
6011 }
6012 else {
6013 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6014 delete sharedLibL;
6015 return -1;
6016 }
6017 rootMapBaseStr += ".rootmap";
6019 if (!rootMap) {
6020 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6021 delete[] rootMap;
6022 delete sharedLibL;
6023 return -1;
6024 }
6025 const Int_t status = LoadLibraryMap(rootMap);
6026 if (status < 0) {
6027 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6028 delete[] rootMap;
6029 delete sharedLibL;
6030 return -1;
6031 }
6032 delete[] rootMap;
6033 }
6034 delete sharedLibL;
6035 return 0;
6036}
6037
6038////////////////////////////////////////////////////////////////////////////////
6039/// Unload the library map entries coming from all the loaded shared libraries.
6040/// Returns 0 if succesful
6041
6043{
6045 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6046 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6047 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6050 }
6051 delete sharedLibL;
6052 return 0;
6053}
6054
6055////////////////////////////////////////////////////////////////////////////////
6056/// Unload library map entries coming from the specified library.
6057/// Returns -1 in case no entries for the specified library were found,
6058/// 0 otherwise.
6059
6061{
6062 if (!fMapfile || !library || !*library) {
6063 return 0;
6064 }
6066 Ssiz_t idx = libname.Last('.');
6067 if (idx != kNPOS) {
6068 libname.Remove(idx);
6069 }
6070 size_t len = libname.Length();
6071 TEnvRec *rec;
6072 TIter next(fMapfile->GetTable());
6074 Int_t ret = 0;
6075 while ((rec = (TEnvRec *) next())) {
6076 TString cls = rec->GetName();
6077 if (cls.Length() > 2) {
6078 // get the first lib from the list of lib and dependent libs
6079 TString libs = rec->GetValue();
6080 if (libs == "") {
6081 continue;
6082 }
6083 TString delim(" ");
6084 TObjArray* tokens = libs.Tokenize(delim);
6085 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6086 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6087 // convert "@@" to "::", we used "@@" because TEnv
6088 // considers "::" a terminator
6089 cls.Remove(0, 8);
6090 cls.ReplaceAll("@@", "::");
6091 // convert "-" to " ", since class names may have
6092 // blanks and TEnv considers a blank a terminator
6093 cls.ReplaceAll("-", " ");
6094 }
6095 if (!strncmp(lib, libname.Data(), len)) {
6096 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6097 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6098 ret = -1;
6099 }
6100 }
6101 delete tokens;
6102 }
6103 }
6104 if (ret >= 0) {
6106 if (!library_rootmap.EndsWith(".rootmap"))
6107 library_rootmap.Append(".rootmap");
6108 TNamed* mfile = nullptr;
6111 delete mfile;
6112 }
6114 }
6115 return ret;
6116}
6117
6118////////////////////////////////////////////////////////////////////////////////
6119/// Register the AutoLoading information for a class.
6120/// libs is a space separated list of libraries.
6121
6122Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6123{
6124 if (!cls || !*cls)
6125 return 0;
6126
6127 TString key = TString("Library.") + cls;
6128 // convert "::" to "@@", we used "@@" because TEnv
6129 // considers "::" a terminator
6130 key.ReplaceAll("::", "@@");
6131 // convert "-" to " ", since class names may have
6132 // blanks and TEnv considers a blank a terminator
6133 key.ReplaceAll(" ", "-");
6134
6136 if (!fMapfile) {
6137 fMapfile = new TEnv();
6139
6142
6143 InitRootmapFile(".rootmap");
6144 }
6145 //fMapfile->SetValue(key, libs);
6147 return 1;
6148}
6149
6150////////////////////////////////////////////////////////////////////////////////
6151/// Demangle the name (from the typeinfo) and then request the class
6152/// via the usual name based interface (TClass::GetClass).
6153
6154TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6155{
6156 int err = 0;
6158 if (err) return nullptr;
6161 return theClass;
6162}
6163
6164////////////////////////////////////////////////////////////////////////////////
6165/// Load library containing the specified class. Returns 0 in case of error
6166/// and 1 in case if success.
6167
6168Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6169{
6170 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6171
6172 int err = 0;
6174 if (err) {
6175 return 0;
6176 }
6177
6178 std::string demangled_name(demangled_name_c);
6180
6181 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6182 // shortened name.
6185
6186 // No need to worry about typedef, they aren't any ... but there are
6187 // inlined namespaces ...
6188
6190 if (result == 0) {
6193 }
6194
6195 return result;
6196}
6197
6198////////////////////////////////////////////////////////////////////////////////
6199// Get the list of 'published'/'known' library for the class and load them.
6201{
6202 Int_t status = 0;
6203
6204 // lookup class to find list of dependent libraries
6206 if (!deplibs.IsNull()) {
6207 TString delim(" ");
6208 TObjArray* tokens = deplibs.Tokenize(delim);
6209 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6210 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6211 if (gROOT->LoadClass(cls, deplib) == 0) {
6212 if (gDebug > 0) {
6213 gCling->Info("TCling::AutoLoad",
6214 "loaded dependent library %s for %s", deplib, cls);
6215 }
6216 }
6217 else {
6218 gCling->Error("TCling::AutoLoad",
6219 "failure loading dependent library %s for %s",
6220 deplib, cls);
6221 }
6222 }
6223 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6224 if (lib && lib[0]) {
6225 if (gROOT->LoadClass(cls, lib) == 0) {
6226 if (gDebug > 0) {
6227 gCling->Info("TCling::AutoLoad",
6228 "loaded library %s for %s", lib, cls);
6229 }
6230 status = 1;
6231 }
6232 else {
6233 gCling->Error("TCling::AutoLoad",
6234 "failure loading library %s for %s", lib, cls);
6235 }
6236 }
6237 delete tokens;
6238 }
6239
6240 return status;
6241}
6242
6243////////////////////////////////////////////////////////////////////////////////
6244// Iterate through the data member of the class (either through the TProtoClass
6245// or through Cling) and trigger, recursively, the loading the necessary libraries.
6246// \note `cls` is expected to be already normalized!
6247// \returns 1 on success.
6248Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6249 bool nameIsNormalized)
6250{
6251 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6252 // has previously (within the same call to `AutoLoad()`) tried to load this class
6253 // and we are done, whether success or not, as it won't work better now than before,
6254 // because there is no additional information now compared to before.
6255 if (!visited.insert(std::string(cls)).second)
6256 return 1;
6257
6258 if (ShallowAutoLoadImpl(cls) == 0) {
6259 // If ShallowAutoLoadImpl() has an error, we have an error.
6260 return 0;
6261 }
6262
6263 // Now look through the TProtoClass to load the required library/dictionary
6265 for (auto element : proto->GetData()) {
6266 if (element->IsBasic())
6267 continue;
6268 const char *subtypename = element->GetTypeName();
6270 // Failure to load a dictionary is not (quite) a failure load
6271 // the top-level library. If we return false here, then
6272 // we would end up in a situation where the library and thus
6273 // the dictionary is loaded for "cls" but the TClass is
6274 // not created and/or marked as unavailable (in case where
6275 // AutoLoad is called from TClass::GetClass).
6276 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6277 }
6278 }
6279 return 1;
6280 }
6281
6282 // We found no TProtoClass for cls.
6283 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6284 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6285 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6286 {
6288 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6289 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6290 continue;
6291 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6293 // Failure to load a dictionary is not (quite) a failure load
6294 // the top-level library. See detailed comment in the TProtoClass
6295 // branch (above).
6296 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6297 }
6298 }
6299 gInterpreter->DataMemberInfo_Delete(memberinfo);
6300 }
6301 gInterpreter->ClassInfo_Delete(classinfo);
6302 return 1;
6303}
6304
6305////////////////////////////////////////////////////////////////////////////////
6306/// Load library containing the specified class. Returns 0 in case of error
6307/// and 1 in case if success.
6308
6310{
6311 // Prevent update to IsClassAutoloading between our check and our actions.
6313
6314 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6315 // rootcling (in *_rdict.pcm file generation) it is a no op.
6316 // FIXME: We should avoid calling autoload when we know we are not supposed
6317 // to and transform this check into an assert.
6319 // Never load any library from rootcling/genreflex.
6320 if (gDebug > 2) {
6321 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6322 }
6323 return 0;
6324 }
6325
6326 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6327
6329
6331 // The library is already loaded as the class's dictionary is known.
6332 // Return success.
6333 // Note: the name (cls) is expected to be normalized as it comes either
6334 // from a callbacks (that can/should calculate the normalized name from the
6335 // decl) or from TClass::GetClass (which does also calculate the normalized
6336 // name).
6337 return 1;
6338 }
6339
6340 if (gDebug > 2) {
6341 Info("TCling::AutoLoad",
6342 "Trying to autoload for %s", cls);
6343 }
6344
6345 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6346 if (gDebug > 2) {
6347 Info("TCling::AutoLoad",
6348 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6349 }
6350 return 0;
6351 }
6352 // Prevent the recursion when the library dictionary are loaded.
6354 // Try using externally provided callback first.
6355 if (fAutoLoadCallBack) {
6357 if (success)
6358 return success;
6359 }
6360
6361 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6362 // (when module are enabled) which might end up calling AutoParsing but
6363 // that should only be for the cases where the library has no generated pcm
6364 // and in that case a rootmap should be available.
6365 // This avoids a very costly operation (for generally no gain) but reduce the
6366 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6367 // file).
6369 std::unordered_set<std::string> visited;
6370 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6371}
6372
6373////////////////////////////////////////////////////////////////////////////////
6374/// Parse the payload or header.
6375
6376static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6377 Bool_t header,
6378 cling::Interpreter *interpreter)
6379{
6380 std::string code = gNonInterpreterClassDef ;
6381 if (!header) {
6382 // This is the complete header file content and not the
6383 // name of a header.
6384 code += what;
6385
6386 } else {
6387 code += ("#include \"");
6388 code += what;
6389 code += "\"\n";
6390 }
6391 code += ("#ifdef __ROOTCLING__\n"
6392 "#undef __ROOTCLING__\n"
6394 "#endif");
6395
6396 cling::Interpreter::CompilationResult cr;
6397 {
6398 // scope within which diagnostics are de-activated
6399 // For now we disable diagnostics because we saw them already at
6400 // dictionary generation time. That won't be an issue with the PCMs.
6401
6402 Sema &SemaR = interpreter->getSema();
6404 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6405
6406 #if defined(R__MUST_REVISIT)
6407 #if R__MUST_REVISIT(6,2)
6408 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6409 #endif
6410 #endif
6411
6412 cr = interpreter->parseForModule(code);
6413 }
6414 return cr;
6415}
6416
6417////////////////////////////////////////////////////////////////////////////////
6418/// Helper routine for TCling::AutoParse implementing the actual call to the
6419/// parser and looping over template parameters (if
6420/// any) and when they don't have a registered header to autoparse,
6421/// recurse over their template parameters.
6422///
6423/// Returns the number of header parsed.
6424
6426{
6427 // We assume the lock has already been taken.
6428 // R__LOCKGUARD(gInterpreterMutex);
6429
6431 unsigned long offset = 0;
6432 if (strncmp(cls, "const ", 6) == 0) {
6433 offset = 6;
6434 }
6435
6436 // Loop on the possible autoparse keys
6437 bool skipFirstEntry = false;
6438 std::vector<std::string> autoparseKeys;
6439 if (strchr(cls, '<')) {
6440 int nestedLoc = 0;
6442 // Check if we can skip the name of the template in the autoparses
6443 // Take all the scopes one by one. If all of them are in the AST, we do not
6444 // need to autoparse for that particular template.
6445 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6446 // autoparseKeys[0] is empty when the input is not a template instance.
6447 // The case strchr(cls, '<') != 0 but still not a template instance can
6448 // happens 'just' for string (GetSplit replaces the template by the short name
6449 // and then use that for thew splitting)
6451 auto tokens = templateName.Tokenize("::");
6452 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6453 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6455 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6456 auto nTokens = tokens->GetEntriesFast();
6457 for (Int_t tk = 0; tk < nTokens; ++tk) {
6458 auto scopeObj = tokens->UncheckedAt(tk);
6459 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6460 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6461 // Check if we have multiple nodes in the AST with this name
6462 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6463 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6464 if (!previousScopeAsContext) break; // this is not a context
6465 }
6466 delete tokens;
6467 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6468 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6469 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6470 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6471 skipFirstEntry = templatedDecl->hasDefinition();
6472 }
6473 }
6474 }
6475
6476 }
6477 }
6478 if (topLevel) autoparseKeys.emplace_back(cls);
6479
6480 for (const auto & apKeyStr : autoparseKeys) {
6481 if (skipFirstEntry) {
6482 skipFirstEntry=false;
6483 continue;
6484 }
6485 if (apKeyStr.empty()) continue;
6486 const char *apKey = apKeyStr.c_str();
6488 // If the class was not looked up
6489 if (gDebug > 1) {
6490 Info("TCling::AutoParse",
6491 "Starting autoparse for %s\n", apKey);
6492 }
6493 if (fLookedUpClasses.insert(normNameHash).second) {
6494 auto const &iter = fClassesHeadersMap.find(normNameHash);
6495 if (iter != fClassesHeadersMap.end()) {
6496 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6498 auto const &hNamesPtrs = iter->second;
6499 if (gDebug > 1) {
6500 Info("TCling::AutoParse",
6501 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6502 }
6503 for (auto & hName : hNamesPtrs) {
6504 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6505 if (0 != fPayloads.count(normNameHash)) {
6506 float initRSSval=0.f, initVSIZEval=0.f;
6507 (void) initRSSval; // Avoid unused var warning
6508 (void) initVSIZEval;
6509 if (gDebug > 0) {
6510 Info("AutoParse",
6511 "Parsing full payload for %s", apKey);
6514 initRSSval = 1e-3*info.fMemResident;
6515 initVSIZEval = 1e-3*info.fMemVirtual;
6516 }
6518 if (cRes != cling::Interpreter::kSuccess) {
6519 if (hName[0] == '\n')
6520 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6521 } else {
6524 if (gDebug > 0){
6527 float endRSSval = 1e-3*info.fMemResident;
6528 float endVSIZEval = 1e-3*info.fMemVirtual;
6529 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6530 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6531 }
6532 }
6533 } else if (!IsLoaded(hName)) {
6534 if (gDebug > 0) {
6535 Info("AutoParse",
6536 "Parsing single header %s", hName);
6537 }
6539 if (cRes != cling::Interpreter::kSuccess) {
6540 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6541 } else {
6543 }
6544 }
6545 }
6546 }
6547 else {
6548 // There is no header registered for this class, if this a
6549 // template, it will be instantiated if/when it is requested
6550 // and if we do no load/parse its components we might end up
6551 // not using an eventual specialization.
6552 if (strchr(apKey, '<')) {
6554 }
6555 }
6556 }
6557 }
6558
6559 return nHheadersParsed;
6560
6561}
6562
6563////////////////////////////////////////////////////////////////////////////////
6564/// Parse the headers relative to the class
6565/// Returns 1 in case of success, 0 in case of failure
6566
6568{
6569 if (llvm::StringRef(cls).contains("(lambda)"))
6570 return 0;
6571
6574 return AutoLoad(cls);
6575 } else {
6576 return 0;
6577 }
6578 }
6579
6581
6582 if (gDebug > 1) {
6583 Info("TCling::AutoParse",
6584 "Trying to autoparse for %s", cls);
6585 }
6586
6587 // The catalogue of headers is in the dictionary
6589 && !gClassTable->GetDictNorm(cls)) {
6590 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6592 fInterpreter->getSema());
6593 AutoLoad(cls, true /*knowDictNotLoaded*/);
6594 }
6595
6596 // Prevent the recursion when the library dictionary are loaded.
6598
6599 // No recursive header parsing on demand; we require headers to be standalone.
6601
6602 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6603
6605
6606 return nHheadersParsed > 0 ? 1 : 0;
6607}
6608
6609// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6610// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6611// false if not.
6612bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6613{
6615 if (errMsg.contains("undefined symbol: ")) {
6616 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6617 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6618 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6619 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6620 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6621 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6622 return true;
6623 } else {
6624 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6626 return true;
6627 }
6628
6629 return false;
6630}
6631
6632////////////////////////////////////////////////////////////////////////////////
6633/// Autoload a library based on a missing symbol.
6634
6637
6638 // We have already loaded the library.
6639 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6640 return Addr;
6641
6642 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6644
6645 auto LibLoader = [](const std::string& LibName) -> bool {
6646 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6647 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6648 "Failed to load library %s", LibName.c_str());
6649 return false;
6650 }
6651 return true; //success.
6652 };
6653
6654 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6655 /*searchSystem=*/ true);
6656
6657 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6658
6659 if (libName.empty())
6660 return nullptr;
6661
6662 if (!LibLoader(libName))
6663 return nullptr;
6664
6665 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6666}
6667
6668////////////////////////////////////////////////////////////////////////////////
6669
6671{
6672 return fNSFromRootmaps.count(nsDecl) != 0;
6673}
6674
6675////////////////////////////////////////////////////////////////////////////////
6676/// Internal function. Actually do the update of the ClassInfo when seeing
6677// new TagDecl or NamespaceDecl.
6678void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6679{
6680
6682 if (cci) {
6683 // If we only had a forward declaration then update the
6684 // TClingClassInfo with the definition if we have it now.
6685 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6686 if (!oldDef || (def && def != oldDef)) {
6687 cl->ResetCaches();
6688 TClass::RemoveClassDeclId(cci->GetDeclId());
6689 if (def) {
6690 if (cci->GetType()) {
6691 // It's a tag decl, not a namespace decl.
6692 cci->Init(*cci->GetType());
6693 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6694 } else {
6695 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6696 }
6697 }
6698 }
6699 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6700 cl->ResetCaches();
6701 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6702 // We need to use the Emulated Tuple but we should not trigger parsing
6703 // yet, so delay the creation of the ClassInfo
6704 delete ((TClingClassInfo *)cl->fClassInfo);
6705 cl->fClassInfo = nullptr;
6706 cl->fCanLoadClassInfo = true;
6708 if (cl->fState != TClass::kHasTClassInit) {
6710 }
6711 return;
6712 }
6713 // yes, this is almost a waste of time, but we do need to lookup
6714 // the 'type' corresponding to the TClass anyway in order to
6715 // preserve the opaque typedefs (Double32_t)
6716 if (!alias && def != nullptr)
6718 else
6720 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6721 // We now need to update the state and bits.
6722 if (cl->fState != TClass::kHasTClassInit) {
6723 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6725 }
6726 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6727 } else {
6728 delete ((TClingClassInfo *)cl->fClassInfo);
6729 cl->fClassInfo = nullptr;
6730 }
6731 }
6732}
6733
6734////////////////////////////////////////////////////////////////////////////////
6735/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6737{
6738 const TagDecl *td = dyn_cast<TagDecl>(ND);
6740 const NamedDecl *canon = nullptr;
6741
6742 std::string name;
6743 TagDecl* tdDef = nullptr;
6744 if (td) {
6745 canon = tdDef = td->getDefinition();
6746 // Let's pass the decl to the TClass only if it has a definition.
6747 if (!tdDef) return;
6748
6749 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6750 // Ignore incomplete definition.
6751 // Ignore declaration within a function.
6752 return;
6753 }
6754
6755 auto declName = tdDef->getNameAsString();
6756 // Check if we have registered the unqualified name into the list
6757 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6758 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6759 // the unqualified name is sufficient (and the fully qualified name might be
6760 // 'wrong' if there is difference in spelling in the template paramters (for example)
6762 // 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() );
6763 return;
6764 }
6765
6766 clang::QualType type(tdDef->getTypeForDecl(), 0);
6768 } else if (ns) {
6769 canon = ns->getCanonicalDecl();
6770 name = ND->getQualifiedNameAsString();
6771 } else {
6772 name = ND->getQualifiedNameAsString();
6773 }
6774
6775 // Supposedly we are being called while something is being
6776 // loaded ... let's now tell the autoloader to do the work
6777 // yet another time.
6779 // FIXME: There can be more than one TClass for a single decl.
6780 // for example vector<double> and vector<Double32_t>
6781 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6782 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6783 RefreshClassInfo(cl, canon, false);
6784 }
6785 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6786 // and update them too:
6787 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6788 // RefreshClassInfo(cl, tdDef, true);
6789}
6790
6791////////////////////////////////////////////////////////////////////////////////
6792/// No op: see TClingCallbacks
6793
6795{
6796}
6797
6798//______________________________________________________________________________
6799//FIXME: Factor out that function in TClass, because TClass does it already twice
6801{
6802 // This is a no-op as part of the API.
6803 // TCling uses UpdateClassInfoWithDecl() instead.
6804}
6805
6806////////////////////////////////////////////////////////////////////////////////
6807/// Update all canvases at end the terminal input command.
6808
6810{
6811 TIter next(gROOT->GetListOfCanvases());
6812 TVirtualPad* canvas;
6813 while ((canvas = (TVirtualPad*)next())) {
6814 canvas->Update();
6815 }
6816}
6817
6818////////////////////////////////////////////////////////////////////////////////
6819
6820void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6821 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6822
6823 // If the transaction does not contain anything we can return earlier.
6824 if (!HandleNewTransaction(T)) return;
6825
6826 bool isTUTransaction = false;
6827 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6828 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6829 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6830 // The is the first transaction, we have to expose to meta
6831 // what's already in the AST.
6832 isTUTransaction = true;
6833 }
6834 }
6835
6836 std::set<const void*> TransactionDeclSet;
6837 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6838 const clang::Decl* WrapperFD = T.getWrapperFD();
6839 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6840 I != E; ++I) {
6841 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6842 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6843 continue;
6844
6845 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6846 DE = I->m_DGR.end(); DI != DE; ++DI) {
6847 if (*DI == WrapperFD)
6848 continue;
6849 TransactionDeclSet.insert(*DI);
6850 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6851 }
6852 }
6853 }
6854
6855 // The above might trigger more decls to be deserialized.
6856 // Thus the iteration over the deserialized decls must be last.
6857 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6858 E = T.deserialized_decls_end(); I != E; ++I) {
6859 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6860 DE = I->m_DGR.end(); DI != DE; ++DI)
6861 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6862 //FIXME: HandleNewDecl should take DeclGroupRef
6863 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6865 }
6866 }
6867
6868
6869 // When fully building the reflection info in TClass, a deserialization
6870 // could be triggered, which may result in request for building the
6871 // reflection info for the same TClass. This in turn will clear the caches
6872 // for the TClass in-flight and cause null ptr derefs.
6873 // FIXME: This is a quick fix, solving most of the issues. The actual
6874 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6875 // itself until the update is done.
6876 //
6877 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6878 std::vector<TClass*>::iterator it;
6880 ((TCling*)gCling)->GetModTClasses().begin(),
6881 ((TCling*)gCling)->GetModTClasses().end(),
6884
6885 // Lock the TClass for updates
6886 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6888 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6889 E = modifiedTClassesDiff.end(); I != E; ++I) {
6890 // Make sure the TClass has not been deleted.
6891 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6892 continue;
6893 }
6894 // Could trigger deserialization of decls.
6895 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6896 // Unlock the TClass for updates
6897 ((TCling*)gCling)->GetModTClasses().erase(*I);
6898
6899 }
6900}
6901
6902///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6903///
6904void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6905{
6907
6908 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6909 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6910 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6911 (TListOfEnums *)gROOT->GetListOfEnums());
6912
6913 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6914 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6915 I != E; ++I) {
6916 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6917 continue;
6918 if (I->m_Call == cling::Transaction::kCCINone) {
6920 ++iNested;
6921 continue;
6922 }
6923
6924 for (auto &D : I->m_DGR)
6926 }
6927}
6928
6929///\brief Invalidate cached TCling information for the given global declaration.
6930///
6932 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6933 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6934 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6935 (TListOfEnums *)gROOT->GetListOfEnums());
6937}
6938
6939///\brief Invalidate cached TCling information for the given declaration, and
6940/// removed it from the appropriate object list.
6941///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6942/// TListOfFunctionTemplates&, TListOfEnums&>
6943/// of pointers to the (global/class) object lists.
6944///\param[in] D - Decl to discard.
6945///
6949 TListOfEnums*> &Lists, const Decl *D) {
6950 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6951 return;
6952
6953 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6954 TListOfFunctions &LOF = *(std::get<1>(Lists));
6955 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6956 TListOfEnums &LOE = *(std::get<3>(Lists));
6957
6959 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6960 if (LODM.GetClass())
6961 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6962 else
6963 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6964 } else if (isa<FunctionDecl>(D)) {
6966 } else if (isa<FunctionTemplateDecl>(D)) {
6968 } else if (isa<EnumDecl>(D)) {
6969 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6970 if (!E)
6971 return;
6972
6973 // Try to invalidate enumerators (for unscoped enumerations).
6974 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6976 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6977
6979 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6981 return;
6982
6983 std::vector<TClass *> Classes;
6984 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6985 return;
6986 for (auto &C : Classes) {
6987 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6988 (TListOfFunctions *)C->GetListOfMethods(),
6989 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6990 (TListOfEnums *)C->GetListOfEnums());
6991 for (auto &I : cast<DeclContext>(D)->decls())
6993
6994 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6995 if (D->getKind() != Decl::Namespace
6996 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6997 C->ResetClassInfo();
6998 }
6999 }
7000}
7001
7002////////////////////////////////////////////////////////////////////////////////
7003// If an autoparse was done during a transaction and that it is rolled back,
7004// we need to make sure the next request for the same autoparse will be
7005// honored.
7006void TCling::TransactionRollback(const cling::Transaction &T) {
7007 auto const &triter = fTransactionHeadersMap.find(&T);
7008 if (triter != fTransactionHeadersMap.end()) {
7009 std::size_t normNameHash = triter->second;
7010
7012
7013 auto const &iter = fClassesHeadersMap.find(normNameHash);
7014 if (iter != fClassesHeadersMap.end()) {
7015 auto const &hNamesPtrs = iter->second;
7016 for (auto &hName : hNamesPtrs) {
7017 if (gDebug > 0) {
7018 Info("TransactionRollback",
7019 "Restoring ability to autoaparse: %s", hName);
7020 }
7022 }
7023 }
7024 }
7025}
7026
7027////////////////////////////////////////////////////////////////////////////////
7028
7029void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7030// R__LOCKGUARD_CLING(gInterpreterMutex);
7031// UpdateListOfLoadedSharedLibraries();
7032}
7033
7034////////////////////////////////////////////////////////////////////////////////
7035
7036void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7037 fPrevLoadedDynLibInfo = nullptr;
7038 fSharedLibs = "";
7039}
7040
7041////////////////////////////////////////////////////////////////////////////////
7042/// Return the list of shared libraries loaded into the process.
7043
7050
7051static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7052{
7053 if (!cls || !*cls)
7054 return {};
7055
7056 using namespace clang;
7057 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7058 /*type*/ nullptr, /*instantiate*/ false)) {
7059 if (!D->isFromASTFile()) {
7060 if (gDebug > 5)
7061 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7062 return {};
7063 }
7064 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7065 llvm::DenseSet<Module *> &m_TopLevelModules;
7066
7067 public:
7068 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7069 void Collect(const Decl *D) { Visit(D); }
7070
7071 void VisitDecl(const Decl *D)
7072 {
7073 // FIXME: Such case is described ROOT-7765 where
7074 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7075 // They are specified as #includes in the LinkDef file. This leads to
7076 // generation of incomplete modulemap files and this logic fails to
7077 // compute the corresponding module of D.
7078 // FIXME: If we want to support such a case, we should not rely on
7079 // the contents of the modulemap but mangle D and look it up in the
7080 // .so files.
7081 if (!D->hasOwningModule())
7082 return;
7083 if (Module *M = D->getOwningModule()->getTopLevelModule())
7084 m_TopLevelModules.insert(M);
7085 }
7086
7088 {
7089 switch (TA.getKind()) {
7090 case TemplateArgument::Null:
7091 case TemplateArgument::Integral:
7092 case TemplateArgument::Pack:
7093 case TemplateArgument::NullPtr:
7094 case TemplateArgument::StructuralValue:
7095 case TemplateArgument::Expression:
7096 case TemplateArgument::Template:
7097 case TemplateArgument::TemplateExpansion: return;
7098 case TemplateArgument::Type:
7099 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7100 return Visit(TagTy->getDecl());
7101 return;
7102 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7103 }
7104 llvm_unreachable("Invalid TemplateArgument::Kind!");
7105 }
7106
7108 {
7109 if (CTSD->getOwningModule())
7110 VisitDecl(CTSD);
7111 else
7112 VisitDecl(CTSD->getSpecializedTemplate());
7113 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7114 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7116 }
7117 }
7118 };
7119
7120 llvm::DenseSet<Module *> TopLevelModules;
7122 m.Collect(D);
7123 std::string result;
7124 for (auto M : TopLevelModules) {
7125 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7126 // link declaration.
7127 if (!M->LinkLibraries.size())
7128 continue;
7129 // We have preloaded the Core module thus libCore.so
7130 if (M->Name == "Core" && skipCore)
7131 continue;
7132 assert(M->LinkLibraries.size() == 1);
7133 if (!result.empty())
7134 result += ' ';
7135 result += M->LinkLibraries[0].Library;
7136 }
7137 return result;
7138 }
7139 return {};
7140}
7141
7142////////////////////////////////////////////////////////////////////////////////
7143/// Get the list of shared libraries containing the code for class cls.
7144/// The first library in the list is the one containing the class, the
7145/// others are the libraries the first one depends on. Returns 0
7146/// in case the library is not found.
7147/// \param cls the name of the class
7148/// \param skipCore if true (default), remove "Core" from the returned list
7149
7150const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7151{
7152 if (fCxxModulesEnabled) {
7153 // Lock the interpreter mutex before interacting with cling.
7154 // TODO: Can we move this further deep? In principle the lock should be in
7155 // GetClassSharedLibsForModule, but it might be needed also for
7156 // getLookupHelper?
7158 llvm::StringRef className = cls;
7159 // If we get a class name containing lambda, we cannot parse it and we
7160 // can exit early.
7161 // FIXME: This works around a bug when we are instantiating a template
7162 // make_unique and the substitution fails. Seen in most of the dataframe
7163 // tests.
7164 if (className.contains("(lambda)"))
7165 return nullptr;
7166 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7168 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7170 if (!libs.empty()) {
7171 fAutoLoadLibStorage.push_back(libs);
7172 return fAutoLoadLibStorage.back().c_str();
7173 }
7174 }
7175
7176 if (!cls || !*cls) {
7177 return nullptr;
7178 }
7179 // lookup class to find list of libraries
7180 if (fMapfile) {
7181 TEnvRec* libs_record = nullptr;
7183 if (libs_record) {
7184 const char* libs = libs_record->GetValue();
7185 return (*libs) ? libs : nullptr;
7186 }
7187 else {
7188 // Try the old format...
7189 TString c = TString("Library.") + cls;
7190 // convert "::" to "@@", we used "@@" because TEnv
7191 // considers "::" a terminator
7192 c.ReplaceAll("::", "@@");
7193 // convert "-" to " ", since class names may have
7194 // blanks and TEnv considers a blank a terminator
7195 c.ReplaceAll(" ", "-");
7196 // Use TEnv::Lookup here as the rootmap file must start with Library.
7197 // and do not support using any stars (so we do not need to waste time
7198 // with the search made by TEnv::GetValue).
7199 TEnvRec* libs_record = nullptr;
7201 if (libs_record) {
7202 const char* libs = libs_record->GetValue();
7203 return (*libs) ? libs : nullptr;
7204 }
7205 }
7206 }
7207 return nullptr;
7208}
7209
7210/// This interface returns a list of dependent libraries in the form:
7211/// lib libA.so libB.so libC.so. The first library is the library we are
7212/// searching dependencies for.
7213/// Note: In order to speed up the search, we display the dependencies of the
7214/// libraries which are not yet loaded. For instance, if libB.so was already
7215/// loaded the list would contain: lib libA.so libC.so.
7216static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7217 cling::Interpreter *interp,
7218 bool skipLoadedLibs = true)
7219{
7220 TString LibFullPath(lib);
7221 if (!llvm::sys::path::is_absolute(lib)) {
7222 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7223 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7224 return "";
7225 }
7226 } else {
7227 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7228 lib = llvm::sys::path::filename(lib).str();
7229 }
7230
7231 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7232 if (!ObjF) {
7233 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7234 return "";
7235 }
7236
7237 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7238
7239 std::set<string> DedupSet;
7240 std::string Result = lib + ' ';
7241 for (const auto &S : BinObjFile->symbols()) {
7242 uint32_t Flags = llvm::cantFail(S.getFlags());
7243 // Skip defined symbols: we have them.
7244 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7245 continue;
7246 // Skip undefined weak symbols: if we don't have them we won't need them.
7247 // `__gmon_start__` being a typical example.
7248 if (Flags & llvm::object::SymbolRef::SF_Weak)
7249 continue;
7250 llvm::Expected<StringRef> SymNameErr = S.getName();
7251 if (!SymNameErr) {
7252 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7253 continue;
7254 }
7255 llvm::StringRef SymName = SymNameErr.get();
7256 if (SymName.empty())
7257 continue;
7258
7259 if (BinObjFile->isELF()) {
7260 // Skip the symbols which are part of the C/C++ runtime and have a
7261 // fixed library version. See binutils ld VERSION. Those reside in
7262 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7263 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7264 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7265 continue;
7266
7267 // Those are 'weak undefined' symbols produced by gcc. We can
7268 // ignore them.
7269 // FIXME: It is unclear whether we can ignore all weak undefined
7270 // symbols:
7271 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7272 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7273 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7274 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7275 if (SymName == RegisterClasses ||
7278 continue;
7279 }
7280
7281 // If we can find the address of the symbol, we have loaded it. Skip.
7282 if (skipLoadedLibs) {
7284 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7285 continue;
7286 }
7287
7289 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7290 // The expected output is just filename without the full path, which
7291 // is not very accurate, because our Dyld implementation might find
7292 // a match in location a/b/c.so and if we return just c.so ROOT might
7293 // resolve it to y/z/c.so and there we might not be ABI compatible.
7294 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7295 if (!found.empty()) {
7296 std::string cand = llvm::sys::path::filename(found).str();
7297 if (!DedupSet.insert(cand).second)
7298 continue;
7299
7300 Result += cand + ' ';
7301 }
7302 }
7303
7304 return Result;
7305}
7306
7307static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7308{
7309 // Check if we have parsed a rootmap file.
7310 llvm::SmallString<256> rootmapName;
7311 if (!lib.starts_with("lib"))
7312 rootmapName.append("lib");
7313
7314 rootmapName.append(llvm::sys::path::filename(lib));
7315 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7316
7317 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7318 return true;
7319
7320 // Perform a last resort by dropping the lib prefix.
7321 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7322 if (rootmapNameNoLib.consume_front("lib"))
7323 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7324
7325 return false;
7326}
7327
7328static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7329{
7330 if (gCling->HasPCMForLibrary(lib.data()))
7331 return true;
7332
7333 return hasParsedRootmapForLibrary(lib);
7334}
7335
7336////////////////////////////////////////////////////////////////////////////////
7337/// Get the list a libraries on which the specified lib depends. The
7338/// returned string contains as first element the lib itself.
7339/// Returns 0 in case the lib does not exist or does not have
7340/// any dependencies. If useDyld is true, we iterate through all available
7341/// libraries and try to construct the dependency chain by resolving each
7342/// symbol.
7343
7344const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7345{
7346 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7347 return nullptr;
7348
7349 if (!hasParsedRootmapForLibrary(lib)) {
7350 llvm::SmallString<512> rootmapName(lib);
7351 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7352 if (llvm::sys::fs::exists(rootmapName)) {
7353 if (gDebug > 0)
7354 Info("Load", "loading %s", rootmapName.c_str());
7355 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7356 }
7357 }
7358
7359 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7360 if (gDebug > 0)
7361 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7362 }
7363
7364 if (useDyld) {
7366 if (!libs.empty()) {
7367 fAutoLoadLibStorage.push_back(libs);
7368 return fAutoLoadLibStorage.back().c_str();
7369 }
7370 }
7371
7372 if (!fMapfile || !lib || !lib[0]) {
7373 return nullptr;
7374 }
7375 TString libname(lib);
7376 Ssiz_t idx = libname.Last('.');
7377 if (idx != kNPOS) {
7378 libname.Remove(idx);
7379 }
7380 TEnvRec* rec;
7381 TIter next(fMapfile->GetTable());
7382 size_t len = libname.Length();
7383 while ((rec = (TEnvRec*) next())) {
7384 const char* libs = rec->GetValue();
7385 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7386 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7387 return libs;
7388 }
7389 }
7390 return nullptr;
7391}
7392
7393////////////////////////////////////////////////////////////////////////////////
7394/// If error messages are disabled, the interpreter should suppress its
7395/// failures and warning messages from stdout.
7396
7398{
7399#if defined(R__MUST_REVISIT)
7400#if R__MUST_REVISIT(6,2)
7401 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7402#endif
7403#endif
7404 return kTRUE;
7405}
7406
7407////////////////////////////////////////////////////////////////////////////////
7408/// If error messages are disabled, the interpreter should suppress its
7409/// failures and warning messages from stdout. Return the previous state.
7410
7412{
7413#if defined(R__MUST_REVISIT)
7414#if R__MUST_REVISIT(6,2)
7415 Warning("SetErrorMessages", "Interface not available yet.");
7416#endif
7417#endif
7419}
7420
7421////////////////////////////////////////////////////////////////////////////////
7422/// Refresh the list of include paths known to the interpreter and return it
7423/// with -I prepended.
7424
7426{
7428
7429 fIncludePath = "";
7430
7431 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7432 //false - no system header, true - with flags.
7433 fInterpreter->GetIncludePaths(includePaths, false, true);
7434 if (const size_t nPaths = includePaths.size()) {
7435 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7436
7437 for (size_t i = 0; i < nPaths; i += 2) {
7438 if (i)
7439 fIncludePath.Append(' ');
7440 fIncludePath.Append(includePaths[i].c_str());
7441
7442 if (includePaths[i] != "-I")
7443 fIncludePath.Append(' ');
7444 fIncludePath.Append('"');
7446 fIncludePath.Append('"');
7447 }
7448 }
7449
7450 return fIncludePath;
7451}
7452
7453////////////////////////////////////////////////////////////////////////////////
7454/// Return the directory containing CINT's stl cintdlls.
7455
7456const char* TCling::GetSTLIncludePath() const
7457{
7458 return "";
7459}
7460
7461//______________________________________________________________________________
7462// M I S C
7463//______________________________________________________________________________
7464
7465int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7466{
7467 // Interface to cling function
7468 return 0;
7469}
7470
7471////////////////////////////////////////////////////////////////////////////////
7472/// Interface to cling function
7473
7475{
7476 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7477
7478 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7479 //false - no system header, true - with flags.
7480 fInterpreter->GetIncludePaths(includePaths, false, true);
7481 if (const size_t nPaths = includePaths.size()) {
7482 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7483
7484 std::string allIncludes("include path:");
7485 for (size_t i = 0; i < nPaths; i += 2) {
7486 allIncludes += ' ';
7488
7489 if (includePaths[i] != "-I")
7490 allIncludes += ' ';
7491 allIncludes += includePaths[i + 1];
7492 }
7493
7494 fprintf(fout, "%s\n", allIncludes.c_str());
7495 }
7496
7497 return 0;
7498}
7499
7500////////////////////////////////////////////////////////////////////////////////
7501/// Interface to cling function
7502
7503void* TCling::FindSym(const char* entry) const
7504{
7506 return fInterpreter->getAddressOfGlobal(entry);
7507}
7508
7509////////////////////////////////////////////////////////////////////////////////
7510/// Let the interpreter issue a generic error, and set its error state.
7511
7512void TCling::GenericError(const char* error) const
7513{
7514#if defined(R__MUST_REVISIT)
7515#if R__MUST_REVISIT(6,2)
7516 Warning("GenericError","Interface not available yet.");
7517#endif
7518#endif
7519}
7520
7521////////////////////////////////////////////////////////////////////////////////
7522/// This routines used to return the address of the internal wrapper
7523/// function (of the interpreter) that was used to call *all* the
7524/// interpreted functions that were bytecode compiled (no longer
7525/// interpreted line by line). In Cling, there is no such
7526/// wrapper function.
7527/// In practice this routines was use to decipher whether the
7528/// pointer returns by InterfaceMethod could be used to uniquely
7529/// represent the function. In Cling if the function is in a
7530/// useable state (its compiled version is available), this is
7531/// always the case.
7532/// See TClass::GetMethod.
7533
7535{
7536 return 0;
7537}
7538
7539////////////////////////////////////////////////////////////////////////////////
7540/// Interface to cling function
7541
7543{
7544#if defined(R__MUST_REVISIT)
7545#if R__MUST_REVISIT(6,2)
7546 Warning("GetSecurityError", "Interface not available yet.");
7547#endif
7548#endif
7549 return 0;
7550}
7551
7552////////////////////////////////////////////////////////////////////////////////
7553/// Load a source file or library called path into the interpreter.
7554
7555int TCling::LoadFile(const char* path) const
7556{
7557 // Modifying the interpreter state needs locking.
7559 cling::Interpreter::CompilationResult compRes;
7560 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7561 return compRes == cling::Interpreter::kFailure;
7562}
7563
7564////////////////////////////////////////////////////////////////////////////////
7565/// Load the declarations from text into the interpreter.
7566/// Note that this cannot be (top level) statements; text must contain
7567/// top level declarations.
7568/// Returns true on success, false on failure.
7569
7570Bool_t TCling::LoadText(const char* text) const
7571{
7572 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7573}
7574
7575////////////////////////////////////////////////////////////////////////////////
7576/// Interface to cling function
7577
7578const char* TCling::MapCppName(const char* name) const
7579{
7580 TTHREAD_TLS_DECL(std::string,buffer);
7582 return buffer.c_str(); // NOLINT
7583}
7584
7585////////////////////////////////////////////////////////////////////////////////
7586/// [Place holder for Mutex Lock]
7587/// Provide the interpreter with a way to
7588/// acquire a lock used to protect critical section
7589/// of its code (non-thread safe parts).
7590
7591void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7592{
7593 // nothing to do for now.
7594}
7595
7596////////////////////////////////////////////////////////////////////////////////
7597/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7598/// release a lock used to protect critical section
7599/// of its code (non-thread safe parts).
7600
7601void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7602{
7603 // nothing to do for now.
7604}
7605
7606////////////////////////////////////////////////////////////////////////////////
7607/// Returns if class AutoLoading is currently enabled.
7608
7610{
7611 if (IsFromRootCling())
7612 return false;
7613 if (!fClingCallbacks)
7614 return false;
7616}
7617
7618////////////////////////////////////////////////////////////////////////////////
7619/// Enable/Disable the AutoLoading of libraries.
7620/// Returns the old value, i.e whether it was enabled or not.
7621
7623{
7624 // If no state change is required, exit early.
7625 // FIXME: In future we probably want to complain if we made a request which
7626 // was with the same state as before in order to catch programming errors.
7627 if ((bool) autoload == IsClassAutoLoadingEnabled())
7628 return autoload;
7629
7630 assert(fClingCallbacks && "We must have callbacks!");
7633 return oldVal;
7634}
7635
7636////////////////////////////////////////////////////////////////////////////////
7637/// Enable/Disable the Autoparsing of headers.
7638/// Returns the old value, i.e whether it was enabled or not.
7639
7646
7647////////////////////////////////////////////////////////////////////////////////
7648/// Suspend the Autoparsing of headers.
7649/// Returns the old value, i.e whether it was suspended or not.
7650
7657
7658////////////////////////////////////////////////////////////////////////////////
7659/// Set a callback to receive error messages.
7660
7662{
7663#if defined(R__MUST_REVISIT)
7664#if R__MUST_REVISIT(6,2)
7665 Warning("SetErrmsgcallback", "Interface not available yet.");
7666#endif
7667#endif
7668}
7669
7671{
7672 if (enable) {
7674 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7675 fInterpreter->getCI()->getLangOpts(),
7676 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7677 if (Level == clang::DiagnosticsEngine::Warning) {
7678 ::Warning("cling", "%s", Info.c_str());
7679 } else if (Level == clang::DiagnosticsEngine::Error
7680 || Level == clang::DiagnosticsEngine::Fatal) {
7681 ::Error("cling", "%s", Info.c_str());
7682 } else {
7683 ::Info("cling", "%s", Info.c_str());
7684 }
7685 });
7686 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7687 } else {
7688 fInterpreter->replaceDiagnosticConsumer(nullptr);
7689 }
7690}
7691
7692
7693////////////////////////////////////////////////////////////////////////////////
7694/// Create / close a scope for temporaries. No-op for cling; use
7695/// cling::Value instead.
7696
7697void TCling::SetTempLevel(int val) const
7698{
7699}
7700
7701////////////////////////////////////////////////////////////////////////////////
7702
7703int TCling::UnloadFile(const char* path) const
7704{
7705 // Modifying the interpreter state needs locking.
7707 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7708 std::string canonical = DLM->lookupLibrary(path);
7709 if (canonical.empty()) {
7710 canonical = path;
7711 }
7712 // Unload a shared library or a source file.
7713 cling::Interpreter::CompilationResult compRes;
7714 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7715 return compRes == cling::Interpreter::kFailure;
7716}
7717
7718std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7719 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7720}
7721
7722////////////////////////////////////////////////////////////////////////////////
7723/// The call to Cling's tab complition.
7724
7725void TCling::CodeComplete(const std::string& line, size_t& cursor,
7726 std::vector<std::string>& completions)
7727{
7728 fInterpreter->codeComplete(line, cursor, completions);
7729}
7730
7731////////////////////////////////////////////////////////////////////////////////
7732/// Get the interpreter value corresponding to the statement.
7734{
7736
7737 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7738 auto compRes = fInterpreter->evaluate(code, *V);
7739 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7740}
7741
7742////////////////////////////////////////////////////////////////////////////////
7743
7745{
7746 using namespace cling;
7747 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7749}
7750
7751////////////////////////////////////////////////////////////////////////////////
7752/// Register value as a temporary, extending its lifetime to that of the
7753/// interpreter. This is needed for TCling's compatibility interfaces
7754/// returning long - the address of the temporary objects.
7755/// As such, "simple" types don't need to be stored; they are returned by
7756/// value; only pointers / references / objects need to be stored.
7757
7758void TCling::RegisterTemporary(const cling::Value& value)
7759{
7760 if (value.isValid() && value.needsManagedAllocation()) {
7762 fTemporaries->push_back(value);
7763 }
7764}
7765
7766////////////////////////////////////////////////////////////////////////////////
7767/// If the interpreter encounters Name, check whether that is an object ROOT
7768/// could retrieve. To not re-read objects from disk, cache the name/object
7769/// pair for a given LookupCtx.
7770
7772{
7773 // The call to FindSpecialObject might induces any kind of use
7774 // of the interpreter ... (library loading, function calling, etc.)
7775 // ... and we _know_ we are in the middle of parsing, so let's make
7776 // sure to save the state and then restore it.
7777
7778 if (gDirectory) {
7780 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7781 auto iSpecObj = iSpecObjMap->second.find(Name);
7782 if (iSpecObj != iSpecObjMap->second.end()) {
7784 return iSpecObj->second;
7785 }
7786 }
7787 }
7788
7789 // Save state of the PP
7790 Sema &SemaR = fInterpreter->getSema();
7791 ASTContext& C = SemaR.getASTContext();
7792 Preprocessor &PP = SemaR.getPreprocessor();
7793 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7794 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7795 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7796 // After we have saved the token reset the current one to something which
7797 // is safe (semi colon usually means empty decl)
7798 Token& Tok = const_cast<Token&>(P.getCurToken());
7799 Tok.setKind(tok::semi);
7800
7801 // We can't PushDeclContext, because we go up and the routine that pops
7802 // the DeclContext assumes that we drill down always.
7803 // We have to be on the global context. At that point we are in a
7804 // wrapper function so the parent context must be the global.
7805 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7806 SemaR.TUScope);
7807
7808 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7809 if (specObj) {
7810 if (!LookupCtx) {
7811 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7812 } else {
7814 }
7815 }
7816 return specObj;
7817}
7818
7819////////////////////////////////////////////////////////////////////////////////
7820/// Inject function as a friend into klass.
7821/// With function being f in void f() {new N::PrivKlass(); } this enables
7822/// I/O of non-public classes.
7823
7824void TCling::AddFriendToClass(clang::FunctionDecl* function,
7825 clang::CXXRecordDecl* klass) const
7826{
7827 using namespace clang;
7828 ASTContext& Ctx = klass->getASTContext();
7829 FriendDecl::FriendUnion friendUnion(function);
7830 // one dummy object for the source location
7832 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7833 klass->pushFriendDecl(friendDecl);
7834}
7835
7836//______________________________________________________________________________
7837//
7838// DeclId getter.
7839//
7840
7841////////////////////////////////////////////////////////////////////////////////
7842/// Return a unique identifier of the declaration represented by the
7843/// CallFunc
7844
7846{
7847 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7848 return nullptr;
7849}
7850
7851////////////////////////////////////////////////////////////////////////////////
7852/// Return a (almost) unique identifier of the declaration represented by the
7853/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7854/// when the underlying class is a template instance involving one of the
7855/// opaque typedef.
7856
7858{
7859 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7860 return nullptr;
7861}
7862
7863////////////////////////////////////////////////////////////////////////////////
7864/// Return a unique identifier of the declaration represented by the
7865/// MethodInfo
7866
7868{
7869 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7870 return nullptr;
7871}
7872
7873////////////////////////////////////////////////////////////////////////////////
7874/// Return a unique identifier of the declaration represented by the
7875/// MethodInfo
7876
7878{
7879 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7880 return nullptr;
7881}
7882
7883////////////////////////////////////////////////////////////////////////////////
7884/// Return a unique identifier of the declaration represented by the
7885/// TypedefInfo
7886
7888{
7889 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7890 return nullptr;
7891}
7892
7893//______________________________________________________________________________
7894//
7895// CallFunc interface
7896//
7897
7898////////////////////////////////////////////////////////////////////////////////
7899
7901{
7902 delete (TClingCallFunc*) func;
7903}
7904
7905////////////////////////////////////////////////////////////////////////////////
7906
7907void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7908{
7909 TClingCallFunc* f = (TClingCallFunc*) func;
7910 f->Exec(address);
7911}
7912
7913////////////////////////////////////////////////////////////////////////////////
7914
7915void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7916{
7917 TClingCallFunc* f = (TClingCallFunc*) func;
7918 f->Exec(address, &val);
7919}
7920
7921////////////////////////////////////////////////////////////////////////////////
7922
7923void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7924{
7925 TClingCallFunc* f = (TClingCallFunc*) func;
7926 f->ExecWithReturn(address, ret);
7927}
7928
7929////////////////////////////////////////////////////////////////////////////////
7930
7932 const void* args[] /*=0*/,
7933 int nargs /*=0*/,
7934 void* ret/*=0*/) const
7935{
7936 TClingCallFunc* f = (TClingCallFunc*) func;
7937 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941
7943{
7944 TClingCallFunc* f = (TClingCallFunc*) func;
7945 return f->ExecInt(address);
7946}
7947
7948////////////////////////////////////////////////////////////////////////////////
7949
7951{
7952 TClingCallFunc* f = (TClingCallFunc*) func;
7953 return f->ExecInt64(address);
7954}
7955
7956////////////////////////////////////////////////////////////////////////////////
7957
7959{
7960 TClingCallFunc* f = (TClingCallFunc*) func;
7961 return f->ExecDouble(address);
7962}
7963
7964////////////////////////////////////////////////////////////////////////////////
7965
7971
7972////////////////////////////////////////////////////////////////////////////////
7973
7975{
7976 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7977}
7978
7979////////////////////////////////////////////////////////////////////////////////
7980
7982{
7983 TClingCallFunc* f = (TClingCallFunc*) func;
7984 return (MethodInfo_t*) f->FactoryMethod();
7985}
7986
7987////////////////////////////////////////////////////////////////////////////////
7988
7990{
7991 TClingCallFunc* f = (TClingCallFunc*) func;
7992 f->IgnoreExtraArgs(ignore);
7993}
7994
7995////////////////////////////////////////////////////////////////////////////////
7996
7998{
8000 TClingCallFunc* f = (TClingCallFunc*) func;
8001 f->Init();
8002}
8003
8004////////////////////////////////////////////////////////////////////////////////
8005
8007{
8008 TClingCallFunc* f = (TClingCallFunc*) func;
8009 return f->IsValid();
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013
8016{
8017 TClingCallFunc* f = (TClingCallFunc*) func;
8018 return f->IFacePtr();
8019}
8020
8021////////////////////////////////////////////////////////////////////////////////
8022
8024{
8025 TClingCallFunc* f = (TClingCallFunc*) func;
8026 f->ResetArg();
8027}
8028
8029////////////////////////////////////////////////////////////////////////////////
8030
8032{
8033 TClingCallFunc* f = (TClingCallFunc*) func;
8034 f->SetArg(param);
8035}
8036
8037////////////////////////////////////////////////////////////////////////////////
8038
8040{
8041 TClingCallFunc* f = (TClingCallFunc*) func;
8042 f->SetArg(param);
8043}
8044
8045////////////////////////////////////////////////////////////////////////////////
8046
8048{
8049 TClingCallFunc* f = (TClingCallFunc*) func;
8050 f->SetArg(param);
8051}
8052
8053////////////////////////////////////////////////////////////////////////////////
8054
8056{
8057 TClingCallFunc* f = (TClingCallFunc*) func;
8058 f->SetArg(param);
8059}
8060
8061////////////////////////////////////////////////////////////////////////////////
8062
8064{
8065 TClingCallFunc* f = (TClingCallFunc*) func;
8066 f->SetArg(param);
8067}
8068
8069////////////////////////////////////////////////////////////////////////////////
8070
8072{
8073 TClingCallFunc* f = (TClingCallFunc*) func;
8074 f->SetArg(param);
8075}
8076
8077////////////////////////////////////////////////////////////////////////////////
8078
8080{
8081 TClingCallFunc* f = (TClingCallFunc*) func;
8082 f->SetArgArray(paramArr, nparam);
8083}
8084
8085////////////////////////////////////////////////////////////////////////////////
8086
8087void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8088{
8089 TClingCallFunc* f = (TClingCallFunc*) func;
8090 f->SetArgs(param);
8091}
8092
8093////////////////////////////////////////////////////////////////////////////////
8094
8095void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8096{
8097 TClingCallFunc* f = (TClingCallFunc*) func;
8099 f->SetFunc(ci, method, params, offset);
8100}
8101
8102////////////////////////////////////////////////////////////////////////////////
8103
8104void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8105{
8106 TClingCallFunc* f = (TClingCallFunc*) func;
8108 f->SetFunc(ci, method, params, objectIsConst, offset);
8109}
8110////////////////////////////////////////////////////////////////////////////////
8111
8112void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8113{
8114 TClingCallFunc* f = (TClingCallFunc*) func;
8116 f->SetFunc(minfo);
8117}
8118
8119////////////////////////////////////////////////////////////////////////////////
8120/// Interface to cling function
8121
8122void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8123{
8124 TClingCallFunc* f = (TClingCallFunc*) func;
8126 f->SetFuncProto(ci, method, proto, offset, mode);
8127}
8128
8129////////////////////////////////////////////////////////////////////////////////
8130/// Interface to cling function
8131
8132void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8133{
8134 TClingCallFunc* f = (TClingCallFunc*) func;
8136 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8137}
8138
8139////////////////////////////////////////////////////////////////////////////////
8140/// Interface to cling function
8141
8142void 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
8143{
8144 TClingCallFunc* f = (TClingCallFunc*) func;
8146 llvm::SmallVector<clang::QualType, 4> funcProto;
8147 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8148 iter != end; ++iter) {
8149 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8150 }
8151 f->SetFuncProto(ci, method, funcProto, offset, mode);
8152}
8153
8154////////////////////////////////////////////////////////////////////////////////
8155/// Interface to cling function
8156
8157void 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
8158{
8159 TClingCallFunc* f = (TClingCallFunc*) func;
8161 llvm::SmallVector<clang::QualType, 4> funcProto;
8162 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8163 iter != end; ++iter) {
8164 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8165 }
8166 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8167}
8168
8170{
8171 TClingCallFunc *f = (TClingCallFunc *)func;
8172 std::string wrapper_name;
8173 std::string wrapper;
8174 f->get_wrapper_code(wrapper_name, wrapper);
8175 return wrapper;
8176}
8177
8178//______________________________________________________________________________
8179//
8180// ClassInfo interface
8181//
8182
8183////////////////////////////////////////////////////////////////////////////////
8184/// Return true if the entity pointed to by 'declid' is declared in
8185/// the context described by 'info'. If info is null, look into the
8186/// global scope (translation unit scope).
8187
8189{
8190 if (!declid)
8191 return kFALSE;
8192
8193 const clang::DeclContext *ctxt = nullptr;
8194 if (info) {
8195 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8196 } else {
8197 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8198 }
8199 if (!ctxt)
8200 return kFALSE;
8201
8202 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8203 if (!decl)
8204 return kFALSE;
8205
8206 const clang::DeclContext *declDC = decl->getDeclContext();
8207 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8208 while (true) {
8209 if (declDC->isTransparentContext()) {
8210 declDC = declDC->getParent();
8211 continue;
8212 }
8213 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8214 if (declRD->isAnonymousStructOrUnion()) {
8215 declDC = declRD->getParent();
8216 continue;
8217 }
8218 }
8219 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8220 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8221 declDC = declNS->getParent();
8222 continue;
8223 }
8224 }
8225 break;
8226 }
8227
8228 return declDC->Equals(ctxt);
8229}
8230
8231////////////////////////////////////////////////////////////////////////////////
8232
8238
8239////////////////////////////////////////////////////////////////////////////////
8240
8242{
8243 delete (TClingClassInfo*) cinfo;
8244}
8245
8246////////////////////////////////////////////////////////////////////////////////
8247
8253
8254////////////////////////////////////////////////////////////////////////////////
8255
8261
8262////////////////////////////////////////////////////////////////////////////////
8263
8269
8270////////////////////////////////////////////////////////////////////////////////
8271
8277
8278////////////////////////////////////////////////////////////////////////////////
8279
8284
8285////////////////////////////////////////////////////////////////////////////////
8286
8292
8298
8299
8300////////////////////////////////////////////////////////////////////////////////
8301
8302int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8303{
8305 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8306}
8307
8308////////////////////////////////////////////////////////////////////////////////
8309
8315
8316////////////////////////////////////////////////////////////////////////////////
8317
8319{
8321 return TClinginfo->HasMethod(name);
8322}
8323
8324////////////////////////////////////////////////////////////////////////////////
8325
8332
8333////////////////////////////////////////////////////////////////////////////////
8334
8336{
8339 TClinginfo->Init(tagnum);
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8345{
8347 return TClinginfo->IsBase(name);
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8352bool TCling::ClassInfo_IsEnum(const char* name) const
8353{
8355}
8356
8357////////////////////////////////////////////////////////////////////////////////
8358
8364
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8373
8374
8375////////////////////////////////////////////////////////////////////////////////
8376
8378{
8380 return TClinginfo->IsLoaded();
8381}
8382
8383////////////////////////////////////////////////////////////////////////////////
8384
8386{
8388 return TClinginfo->IsValid();
8389}
8390
8391////////////////////////////////////////////////////////////////////////////////
8392
8393bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8394{
8396 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8397}
8398
8399////////////////////////////////////////////////////////////////////////////////
8400
8402{
8404 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8405}
8406
8407////////////////////////////////////////////////////////////////////////////////
8408
8414
8415////////////////////////////////////////////////////////////////////////////////
8416
8422
8423////////////////////////////////////////////////////////////////////////////////
8424
8430
8431////////////////////////////////////////////////////////////////////////////////
8432
8434{
8436 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8437}
8438
8439////////////////////////////////////////////////////////////////////////////////
8440
8446
8447////////////////////////////////////////////////////////////////////////////////
8448
8454
8455////////////////////////////////////////////////////////////////////////////////
8456
8462
8463////////////////////////////////////////////////////////////////////////////////
8464
8470
8471////////////////////////////////////////////////////////////////////////////////
8472
8474{
8476 return TClinginfo->FileName();
8477}
8478
8479////////////////////////////////////////////////////////////////////////////////
8480
8482{
8484 TTHREAD_TLS_DECL(std::string,output);
8485 TClinginfo->FullName(output,*fNormalizedCtxt);
8486 return output.c_str(); // NOLINT
8487}
8488
8489////////////////////////////////////////////////////////////////////////////////
8490
8492{
8494 return TClinginfo->Name();
8495}
8496
8497////////////////////////////////////////////////////////////////////////////////
8498
8500{
8502 return TClinginfo->Title();
8503}
8504
8505////////////////////////////////////////////////////////////////////////////////
8506
8508{
8510 return TClinginfo->TmpltName();
8511}
8512
8513
8514
8515//______________________________________________________________________________
8516//
8517// BaseClassInfo interface
8518//
8519
8520////////////////////////////////////////////////////////////////////////////////
8521
8526
8527////////////////////////////////////////////////////////////////////////////////
8528
8535
8536////////////////////////////////////////////////////////////////////////////////
8537
8546
8547////////////////////////////////////////////////////////////////////////////////
8548
8554
8555////////////////////////////////////////////////////////////////////////////////
8556
8562
8563////////////////////////////////////////////////////////////////////////////////
8564
8570
8571////////////////////////////////////////////////////////////////////////////////
8572
8574{
8577 // Offset to the class itself.
8578 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8579 return 0;
8580 }
8581 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8582}
8583
8584////////////////////////////////////////////////////////////////////////////////
8585
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8599
8600////////////////////////////////////////////////////////////////////////////////
8601
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8611{
8613 TTHREAD_TLS_DECL(std::string,output);
8614 TClinginfo->FullName(output,*fNormalizedCtxt);
8615 return output.c_str(); // NOLINT
8616}
8617
8618////////////////////////////////////////////////////////////////////////////////
8619
8625
8626////////////////////////////////////////////////////////////////////////////////
8627
8633
8634//______________________________________________________________________________
8635//
8636// DataMemberInfo interface
8637//
8638
8639////////////////////////////////////////////////////////////////////////////////
8640
8646
8647////////////////////////////////////////////////////////////////////////////////
8648
8653
8654////////////////////////////////////////////////////////////////////////////////
8655
8662
8663////////////////////////////////////////////////////////////////////////////////
8664
8666{
8668 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8669 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8671}
8672
8673////////////////////////////////////////////////////////////////////////////////
8674
8680
8681////////////////////////////////////////////////////////////////////////////////
8682
8688
8689////////////////////////////////////////////////////////////////////////////////
8690
8696
8697////////////////////////////////////////////////////////////////////////////////
8698
8704
8705////////////////////////////////////////////////////////////////////////////////
8706
8712
8713////////////////////////////////////////////////////////////////////////////////
8714
8720
8721////////////////////////////////////////////////////////////////////////////////
8722
8728
8729////////////////////////////////////////////////////////////////////////////////
8730
8736
8737////////////////////////////////////////////////////////////////////////////////
8738
8744
8745////////////////////////////////////////////////////////////////////////////////
8746
8752
8753////////////////////////////////////////////////////////////////////////////////
8754
8760
8761////////////////////////////////////////////////////////////////////////////////
8762
8768
8769////////////////////////////////////////////////////////////////////////////////
8770
8772{
8773 TTHREAD_TLS_DECL(std::string,result);
8774
8776 result = TClinginfo->ValidArrayIndex().str();
8777 return result.c_str(); // NOLINT
8778}
8779
8780////////////////////////////////////////////////////////////////////////////////
8781
8783{
8784 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8785 ASTContext &C = decl->getASTContext();
8786 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8787}
8788
8789//______________________________________________________________________________
8790//
8791// Function Template interface
8792//
8793
8794////////////////////////////////////////////////////////////////////////////////
8795
8796static void ConstructorName(std::string &name, const clang::Decl *decl,
8797 cling::Interpreter &interp,
8799{
8800 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8801 if (!td) return;
8802
8803 clang::QualType qualType(td->getTypeForDecl(),0);
8805 unsigned int level = 0;
8806 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8807 if (name[cursor] == '>') ++level;
8808 else if (name[cursor] == '<' && level) --level;
8809 else if (level == 0 && name[cursor] == ':') {
8810 name.erase(0,cursor+1);
8811 break;
8812 }
8813 }
8814}
8815
8816////////////////////////////////////////////////////////////////////////////////
8817
8818void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8819{
8820 output.clear();
8821
8822 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8823 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8824 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8825 }
8826 if (!FD) {
8827 Error("GetFunctionName", "NULL Decl!");
8828 return;
8829 }
8830
8831 // For using-decls, show "Derived", not "Base", i.e. use the
8832 // name of the decl context of the UsingShadowDecl (aka `decl`)
8833 // not the name of FD's decl context.
8834 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8835 {
8837
8838 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8839 {
8841 output.insert(output.begin(), '~');
8842 } else {
8843 llvm::raw_string_ostream stream(output);
8844 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8845 // Don't trigger fopen of the source file to count lines:
8846 printPolicy.AnonymousTagLocations = false;
8847 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8848 }
8849}
8850
8851////////////////////////////////////////////////////////////////////////////////
8852/// Return a unique identifier of the declaration represented by the
8853/// FuncTempInfo
8854
8859
8860////////////////////////////////////////////////////////////////////////////////
8861/// Delete the FuncTempInfo_t
8862
8864{
8865 // Currently the address of ft_info is actually the decl itself,
8866 // so we have nothing to do.
8867}
8868
8869////////////////////////////////////////////////////////////////////////////////
8870/// Construct a FuncTempInfo_t
8871
8873{
8874 // Currently the address of ft_info is actually the decl itself,
8875 // so we have nothing to do.
8876
8877 return (FuncTempInfo_t*)const_cast<void*>(declid);
8878}
8879
8880////////////////////////////////////////////////////////////////////////////////
8881/// Construct a FuncTempInfo_t
8882
8884{
8885 // Currently the address of ft_info is actually the decl itself,
8886 // so we have nothing to do.
8887
8888 return (FuncTempInfo_t*)ft_info;
8889}
8890
8891////////////////////////////////////////////////////////////////////////////////
8892/// Check validity of a FuncTempInfo_t
8893
8895{
8896 // Currently the address of ft_info is actually the decl itself,
8897 // so we have nothing to do.
8898
8899 return t_info != nullptr;
8900}
8901
8902////////////////////////////////////////////////////////////////////////////////
8903/// Return the maximum number of template arguments of the
8904/// function template described by ft_info.
8905
8907{
8908 if (!ft_info) return 0;
8909 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8910 return ft->getTemplateParameters()->size();
8911}
8912
8913////////////////////////////////////////////////////////////////////////////////
8914/// Return the number of required template arguments of the
8915/// function template described by ft_info.
8916
8918{
8919 if (!ft_info) return 0;
8920 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8921 return ft->getTemplateParameters()->getMinRequiredArguments();
8922}
8923
8924////////////////////////////////////////////////////////////////////////////////
8925/// Return the property of the function template.
8926
8928{
8929 if (!ft_info) return 0;
8930
8931 long property = 0L;
8932 property |= kIsCompiled;
8933
8934 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8935
8936 switch (ft->getAccess()) {
8937 case clang::AS_public:
8938 property |= kIsPublic;
8939 break;
8940 case clang::AS_protected:
8941 property |= kIsProtected;
8942 break;
8943 case clang::AS_private:
8944 property |= kIsPrivate;
8945 break;
8946 case clang::AS_none:
8947 if (ft->getDeclContext()->isNamespace())
8949 break;
8950 default:
8951 // IMPOSSIBLE
8952 assert(false && "Unexpected value for the access property value in Clang");
8953 break;
8954 }
8955
8956 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8957 if (const clang::CXXMethodDecl *md =
8958 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8959 if (md->getMethodQualifiers().hasConst()) {
8960 property |= kIsConstant | kIsConstMethod;
8961 }
8962 if (md->isVirtual()) {
8963 property |= kIsVirtual;
8964 }
8965 if (md->isPureVirtual()) {
8966 property |= kIsPureVirtual;
8967 }
8968 if (const clang::CXXConstructorDecl *cd =
8969 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8970 if (cd->isExplicit()) {
8971 property |= kIsExplicit;
8972 }
8973 }
8974 else if (const clang::CXXConversionDecl *cd =
8975 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8976 if (cd->isExplicit()) {
8977 property |= kIsExplicit;
8978 }
8979 }
8980 }
8981 return property;
8982}
8983
8984////////////////////////////////////////////////////////////////////////////////
8985/// Return the property not already defined in Property
8986/// See TDictionary's EFunctionProperty
8987
8989{
8990 if (!ft_info) return 0;
8991
8992 long property = 0L;
8993 property |= kIsCompiled;
8994
8995 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8996 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8997
8998 if (fd->isOverloadedOperator())
9000 if (llvm::isa<clang::CXXConversionDecl>(fd))
9002 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9004 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9006 if (fd->isInlined())
9008 return property;
9009}
9010
9011////////////////////////////////////////////////////////////////////////////////
9012/// Return the name of this function template.
9013
9015{
9016 output.Clear();
9017 if (!ft_info) return;
9018 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9019 std::string buf;
9020 GetFunctionName(ft->getTemplatedDecl(), buf);
9021 output = buf;
9022}
9023
9024////////////////////////////////////////////////////////////////////////////////
9025/// Return the comments associates with this function template.
9026
9028{
9029 output.Clear();
9030 if (!ft_info) return;
9031 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9032
9033 // Iterate over the redeclarations, we can have multiple definitions in the
9034 // redecl chain (came from merging of pcms).
9037 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9038 output = A->getAnnotation().str();
9039 return;
9040 }
9041 }
9042 if (!ft->isFromASTFile()) {
9043 // Try to get the comment from the header file if present
9044 // but not for decls from AST file, where rootcling would have
9045 // created an annotation
9047 }
9048}
9049
9050
9051//______________________________________________________________________________
9052//
9053// MethodInfo interface
9054//
9055
9056////////////////////////////////////////////////////////////////////////////////
9057/// Interface to cling function
9058
9059void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9060{
9061 delete(TClingMethodInfo*) minfo;
9062}
9063
9064////////////////////////////////////////////////////////////////////////////////
9065
9067{
9069 // The next call locks the interpreter mutex.
9070 info->CreateSignature(signature);
9071}
9072
9073////////////////////////////////////////////////////////////////////////////////
9074
9075MethodInfo_t* TCling::MethodInfo_Factory() const
9076{
9078 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9079}
9080
9081////////////////////////////////////////////////////////////////////////////////
9082
9084{
9086 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9087}
9088
9089////////////////////////////////////////////////////////////////////////////////
9090
9092{
9093 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9095 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9096}
9097
9098////////////////////////////////////////////////////////////////////////////////
9099
9100MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9101{
9102 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9103}
9104
9105////////////////////////////////////////////////////////////////////////////////
9106
9108{
9110 // The next call locks the interpreter mutex.
9111 return info->InterfaceMethod();
9112}
9113
9114////////////////////////////////////////////////////////////////////////////////
9115
9116bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9117{
9119 return info->IsValid();
9120}
9121
9122////////////////////////////////////////////////////////////////////////////////
9123
9124int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9125{
9127 return info->NArg();
9128}
9129
9130////////////////////////////////////////////////////////////////////////////////
9131
9133{
9135 return info->NDefaultArg();
9136}
9137
9138////////////////////////////////////////////////////////////////////////////////
9139
9140int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9141{
9143 return info->Next();
9144}
9145
9146////////////////////////////////////////////////////////////////////////////////
9147
9149{
9151 // The next call locks the interpreter mutex.
9152 return info->Property();
9153}
9154
9155////////////////////////////////////////////////////////////////////////////////
9156
9158{
9160 // The next call locks the interpreter mutex.
9161 return info->ExtraProperty();
9162}
9163
9164////////////////////////////////////////////////////////////////////////////////
9165
9167{
9169 // The next call locks the interpreter mutex.
9170 return (TypeInfo_t*)info->Type();
9171}
9172
9173////////////////////////////////////////////////////////////////////////////////
9174
9175const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9176{
9179 // The next call locks the interpreter mutex.
9180 mangled_name = info->GetMangledName();
9181 return mangled_name;
9182}
9183
9184////////////////////////////////////////////////////////////////////////////////
9185
9186const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9187{
9189 // The next call locks the interpreter mutex.
9190 return info->GetPrototype();
9191}
9192
9193////////////////////////////////////////////////////////////////////////////////
9194
9195const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9196{
9198 // The next call locks the interpreter mutex.
9199 return info->Name();
9200}
9201
9202////////////////////////////////////////////////////////////////////////////////
9203
9204const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9205{
9207 // The next call locks the interpreter mutex.
9208 return info->TypeName();
9209}
9210
9211////////////////////////////////////////////////////////////////////////////////
9212
9213std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9214{
9216 // The next part locks the interpreter mutex.
9217 if (info && info->IsValid())
9218 return info->Type()->NormalizedName(*fNormalizedCtxt);
9219 else
9220 return "";
9221}
9222
9223////////////////////////////////////////////////////////////////////////////////
9224
9225const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9226{
9228 // The next call locks the interpreter mutex.
9229 return info->Title();
9230}
9231
9232////////////////////////////////////////////////////////////////////////////////
9233
9235{
9236 if (func) {
9237 return MethodInfo_MethodCallReturnType(func->fInfo);
9238 } else {
9239 return EReturnType::kOther;
9240 }
9241}
9242
9243////////////////////////////////////////////////////////////////////////////////
9244
9246{
9248 if (info && info->IsValid()) {
9249 TClingTypeInfo *typeinfo = info->Type();
9250 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9251 if (QT->isEnumeralType()) {
9252 return EReturnType::kLong;
9253 } else if (QT->isPointerType()) {
9254 // Look for char*
9255 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9256 if ( QT->isCharType() ) {
9257 return EReturnType::kString;
9258 } else {
9259 return EReturnType::kOther;
9260 }
9261 } else if ( QT->isFloatingType() ) {
9262 int sz = typeinfo->Size();
9263 if (sz == 4 || sz == 8) {
9264 // Support only float and double.
9265 return EReturnType::kDouble;
9266 } else {
9267 return EReturnType::kOther;
9268 }
9269 } else if ( QT->isIntegerType() ) {
9270 int sz = typeinfo->Size();
9271 if (sz <= 8) {
9272 // Support only up to long long ... but
9273 // FIXME the TMethodCall::Execute only
9274 // return long (4 bytes) ...
9275 // The v5 implementation of TMethodCall::ReturnType
9276 // was not making the distinction so we let it go
9277 // as is for now, but we really need to upgrade
9278 // TMethodCall::Execute ...
9279 return EReturnType::kLong;
9280 } else {
9281 return EReturnType::kOther;
9282 }
9283 } else {
9284 return EReturnType::kOther;
9285 }
9286 } else {
9287 return EReturnType::kOther;
9288 }
9289}
9290
9291//______________________________________________________________________________
9292//
9293// MethodArgInfo interface
9294//
9295
9296////////////////////////////////////////////////////////////////////////////////
9297
9302
9303////////////////////////////////////////////////////////////////////////////////
9304
9310
9311////////////////////////////////////////////////////////////////////////////////
9312
9318
9319////////////////////////////////////////////////////////////////////////////////
9320
9326
9327////////////////////////////////////////////////////////////////////////////////
9328
9334
9335////////////////////////////////////////////////////////////////////////////////
9336
9342
9343////////////////////////////////////////////////////////////////////////////////
9344
9350
9351////////////////////////////////////////////////////////////////////////////////
9352
9354{
9356 return info->DefaultValue();
9357}
9358
9359////////////////////////////////////////////////////////////////////////////////
9360
9362{
9364 return info->Name();
9365}
9366
9367////////////////////////////////////////////////////////////////////////////////
9368
9370{
9372 return info->TypeName();
9373}
9374
9375////////////////////////////////////////////////////////////////////////////////
9376
9378{
9380 return info->Type()->NormalizedName(*fNormalizedCtxt);
9381}
9382
9383////////////////////////////////////////////////////////////////////////////////
9384
9390
9391//______________________________________________________________________________
9392//
9393// TypeInfo interface
9394//
9395
9396////////////////////////////////////////////////////////////////////////////////
9397
9399{
9400 delete (TClingTypeInfo*) tinfo;
9401}
9402
9403////////////////////////////////////////////////////////////////////////////////
9404
9410
9411////////////////////////////////////////////////////////////////////////////////
9412
9418
9419////////////////////////////////////////////////////////////////////////////////
9420
9425
9426////////////////////////////////////////////////////////////////////////////////
9427
9434
9435////////////////////////////////////////////////////////////////////////////////
9436
9438{
9440 return TClinginfo->IsValid();
9441}
9442
9443////////////////////////////////////////////////////////////////////////////////
9444
9446{
9448 return TClinginfo->Name();
9449}
9450
9451////////////////////////////////////////////////////////////////////////////////
9452
9458
9459////////////////////////////////////////////////////////////////////////////////
9460
9462{
9464 return TClinginfo->RefType();
9465}
9466
9467////////////////////////////////////////////////////////////////////////////////
9468
9470{
9472 return TClinginfo->Size();
9473}
9474
9475////////////////////////////////////////////////////////////////////////////////
9476
9478{
9480 return TClinginfo->TrueName(*fNormalizedCtxt);
9481}
9482
9483////////////////////////////////////////////////////////////////////////////////
9484
9486{
9488 return TClinginfo->QualTypePtr();
9489}
9490
9491
9492//______________________________________________________________________________
9493//
9494// TypedefInfo interface
9495//
9496
9497////////////////////////////////////////////////////////////////////////////////
9498
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9511
9512////////////////////////////////////////////////////////////////////////////////
9513
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9526
9527////////////////////////////////////////////////////////////////////////////////
9528
9536
9537////////////////////////////////////////////////////////////////////////////////
9538
9544
9545////////////////////////////////////////////////////////////////////////////////
9546
9552
9553////////////////////////////////////////////////////////////////////////////////
9554
9560
9561////////////////////////////////////////////////////////////////////////////////
9562
9568
9569////////////////////////////////////////////////////////////////////////////////
9570
9576
9577////////////////////////////////////////////////////////////////////////////////
9578
9580{
9582 return TClinginfo->Name();
9583}
9584
9585////////////////////////////////////////////////////////////////////////////////
9586
9588{
9590 return TClinginfo->Title();
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594
9595bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9596{
9597 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9598 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9599 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9600}
9601
9602////////////////////////////////////////////////////////////////////////////////
9603
9604bool TCling::IsIntegerType(const void * QualTypePtr) const
9605{
9606 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9607 return QT->hasIntegerRepresentation();
9608}
9609
9610////////////////////////////////////////////////////////////////////////////////
9611
9612bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9613{
9614 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9615 return QT->hasSignedIntegerRepresentation();
9616}
9617
9618////////////////////////////////////////////////////////////////////////////////
9619
9620bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9621{
9622 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9623 return QT->hasUnsignedIntegerRepresentation();
9624}
9625
9626////////////////////////////////////////////////////////////////////////////////
9627
9628bool TCling::IsFloatingType(const void * QualTypePtr) const
9629{
9630 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9631 return QT->hasFloatingRepresentation();
9632}
9633
9634////////////////////////////////////////////////////////////////////////////////
9635
9636bool TCling::IsPointerType(const void * QualTypePtr) const
9637{
9638 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9639 return QT->hasPointerRepresentation();
9640}
9641
9642////////////////////////////////////////////////////////////////////////////////
9643
9644bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9645{
9646 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9647 return QT->isVoidPointerType();
9648}
9649
9650////////////////////////////////////////////////////////////////////////////////
9651
9653{
9654 if (!fInitialMutex) {
9656 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9657 }
9658 fInitialMutex.fState = mtx->GetStateBefore();
9659 }
9660 // We will "forget" this lock once we backed out of all interpreter frames.
9661 // Here we are entering one, so ++.
9663}
9664
9665////////////////////////////////////////////////////////////////////////////////
9666
9668{
9669 if (!fInitialMutex)
9670 return;
9671 if (fInitialMutex.fRecurseCount == 0) {
9672 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9673 }
9674 else if (--fInitialMutex.fRecurseCount == 0) {
9675 // We have returned from all interpreter frames. Reset the initial lock state.
9676 fInitialMutex.fState.reset();
9677 }
9678}
9679
9680////////////////////////////////////////////////////////////////////////////////
9681/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9682
9684{
9685 if (gInterpreterMutex) {
9686 if (delta) {
9687 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9688 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9689 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9690 // Now that we have the lock, update the global
9691 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9692 std::swap(fInitialMutex, typedDelta->fInitialState);
9693 } else {
9694 // This case happens when EnableThreadSafety is first called from
9695 // the interpreter function we just handled.
9696 // Since thread safety was not enabled at the time we rewound, there was
9697 // no lock taken and even-though we should be locking the rest of this
9698 // interpreter handling/modifying code (since there might be threads in
9699 // flight), we can't because there would not be any lock guard to release the
9700 // locks
9702 Error("ApplyToInterpreterMutex",
9703 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9704 "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.");
9705 }
9706 }
9707}
9708
9709////////////////////////////////////////////////////////////////////////////////
9710/// Reset the interpreter lock to the state it had before interpreter-related
9711/// calls happened.
9712
9714{
9715 if (fInitialMutex) {
9716 // Need to start a new recurse count.
9717 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9718 std::swap(uniqueP->fInitialState, fInitialMutex);
9719 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9720 return uniqueP.release();
9721 }
9723 return nullptr;
9724}
#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 R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:75
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:94
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:117
long long Long64_t
Definition RtypesCore.h:69
unsigned long long ULong64_t
Definition RtypesCore.h:70
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:85
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:343
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:581
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1319
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7307
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:576
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:896
R__EXTERN int optind
Definition TCling.cxx:319
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:370
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:571
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:559
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:335
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:226
bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
Check if the class name is present in TClassTable.
Definition TCling.cxx:1005
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3949
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:353
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1971
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3173
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:635
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1100
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:905
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:1085
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:381
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:3991
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1694
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:630
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:223
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:701
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1099
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:253
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:595
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:566
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:606
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3967
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:590
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:391
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:217
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:646
#define R__DLLEXPORT
Definition TCling.cxx:153
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:362
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:235
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:625
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1050
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1203
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8796
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:328
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:2456
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:7216
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:238
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:682
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1996
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:610
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:7051
const char * fantomline
Definition TCling.cxx:843
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:585
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6376
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5556
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:220
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:602
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:1072
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:641
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:618
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7328
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:653
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
@ kIsNotReacheable
Definition TDictionary.h:87
#define gDirectory
Definition TDirectory.h:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
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 data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
void cd(Int_t id=-1)
Int_t Collect(const TSlave *sl, Long_t timeout=-1, Int_t endtype=-1, Bool_t deactonfail=kFALSE)
Int_t gDebug
Definition TROOT.cxx:622
#define gROOT
Definition TROOT.h:414
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17535
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
const_iterator begin() const
const_iterator end() const
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:29
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3571
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2992
void RemoveStreamerInfo(Int_t slot)
Remove and delete the StreamerInfo in the given slot.
Definition TClass.cxx:7510
EState fState
cached of the streaming method to use
Definition TClass.h:280
std::atomic< TList * > fBase
Definition TClass.h:204
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:576
Version_t fClassVersion
Definition TClass.h:224
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3926
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:5043
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:603
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3530
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5889
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5844
@ kLoading
Definition TClass.h:335
@ kUnloading
Definition TClass.h:335
TObjArray * fStreamerInfo
Definition TClass.h:201
ClassInfo_t * GetClassInfo() const
Definition TClass.h:440
ClassInfo_t * fClassInfo
Definition TClass.h:225
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:3003
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4343
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1912
@ kInterpreted
Definition TClass.h:129
@ kHasTClassInit
Definition TClass.h:130
@ kEmulated
Definition TClass.h:128
@ kForwardDeclared
Definition TClass.h:127
@ kNamespaceForMeta
Definition TClass.h:134
std::atomic< Bool_t > fCanLoadClassInfo
Whether info was loaded from a root pcm.
Definition TClass.h:263
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:262
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3595
@ kIsTObject
Definition TClass.h:103
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:3074
Emulation of the CINT BaseClassInfo class.
const char * Name() const
Emulation of the CINT CallFunc class.
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
static bool IsEnum(cling::Interpreter *interp, const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) 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
TClingMethodInfo GetMethod(const char *fname) const
const clang::ValueDecl * GetDataMember(const char *name) const
Emulation of the CINT DataMemberInfo class.
virtual const char * Name() const
virtual bool IsValid() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
Emulation of the CINT MethodInfo class.
TDictionary::DeclId_t GetDeclId() const
Emulation of the CINT TypeInfo class.
Emulation of the CINT TypedefInfo class.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1026
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1034
std::string fContent
Definition TCling.h:618
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:6248
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9353
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8359
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9445
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9107
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4439
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3929
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9539
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6309
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7997
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:3692
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6612
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7512
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7923
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9166
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7900
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:7555
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3768
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8782
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:498
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:6946
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9148
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4486
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8393
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8715
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7640
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:4533
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3813
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8385
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6820
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9461
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4415
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8272
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9195
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8529
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7570
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7344
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9245
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7771
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3604
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9116
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8872
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9405
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7609
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6931
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7733
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7718
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3392
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9587
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:8122
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5699
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:6567
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1843
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4551
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1646
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7824
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2681
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8549
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6678
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7974
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7958
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8023
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5507
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3216
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3916
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7989
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9683
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6635
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:4767
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:8188
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3182
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:7534
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8641
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9385
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8675
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3709
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:5572
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8409
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7661
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9329
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9469
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3827
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7542
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7697
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:8906
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:5199
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9506
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9644
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2486
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8457
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9369
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:643
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5447
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8699
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9579
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8522
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9157
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3596
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8883
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8691
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8894
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:2695
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8344
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3727
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8739
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4994
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8079
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8169
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9713
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9361
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3191
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9529
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8763
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7942
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3129
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:7591
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:7411
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7981
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9620
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9522
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:5092
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:2426
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9377
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:4876
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9345
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9563
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7931
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:5244
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:633
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6800
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3559
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9547
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:5051
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9428
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7651
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8731
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8499
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8755
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5522
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9612
void ForgetMutexState() final
Definition TCling.cxx:9667
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9140
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8233
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9059
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9298
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8656
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8264
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:6154
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6042
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8326
std::set< TClass * > & GetModTClasses()
Definition TCling.h:578
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8594
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7950
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8449
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8573
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:423
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5429
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7397
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7474
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7006
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8927
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:471
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9477
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6060
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7744
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7044
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9337
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9652
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9453
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9186
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:8917
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:2043
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6200
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9066
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4393
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7029
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:2417
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8683
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8352
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9132
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4542
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5969
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:7670
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9175
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9604
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:590
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:5154
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8417
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7465
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8818
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4567
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7456
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9321
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8565
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:4221
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7503
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3459
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9398
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9124
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4985
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9234
void ProcessClassesToUpdate()
Definition TCling.cxx:2012
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:5177
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:5006
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9225
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8628
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:3142
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8610
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8087
int UnloadFile(const char *path) const final
Definition TCling.cxx:7703
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4085
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7907
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9636
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9628
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8988
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8006
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8620
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8771
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4588
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1043
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4916
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5277
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8377
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8465
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8586
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8095
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4522
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8473
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9027
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8507
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3903
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1727
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6670
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:3784
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7725
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:3798
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7578
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3629
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5981
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3936
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8649
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:5460
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:4560
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:2717
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6122
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9100
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8015
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9305
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6794
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:5073
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8241
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8368
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8863
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:5221
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3842
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:7150
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8707
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7966
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9075
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8723
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3121
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:644
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2475
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:7601
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
bool IsValid() const final
Check if constructor exited correctly, ie the instance is in a valid state.
Definition TCling.cxx:3112
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2391
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9499
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3752
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9571
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7622
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8481
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:6425
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9204
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8031
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7425
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6904
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6736
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9595
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1664
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:8302
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:4815
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:9014
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9437
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1938
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9213
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8491
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4598
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8310
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3165
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9421
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9485
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8318
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8256
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:8747
virtual void ShutDown() final
Definition TCling.cxx:1685
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3943
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9555
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1708
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:3613
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:5033
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6809
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5785
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8602
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7036
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.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:182
@ kNone
Definition TEnum.h:49
@ kAutoload
Definition TEnum.h:50
Definition TEnv.h:86
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:131
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * Remove(TObject *obj) override
Remove object from the list.
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
This class defines an abstract interface to a generic command line interpreter.
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
virtual Bool_t Declare(const char *code)=0
virtual const char * GetClassSharedLibs(const char *cls, bool skipCore=true)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A doubly linked list.
Definition TList.h:38
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx: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.
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TNamed()
Definition TNamed.h:38
An array of TObjects.
Definition TObjArray.h:31
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:205
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:158
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:421
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
virtual TClass * IsA() const
Definition TObject.h:249
void MakeZombie()
Definition TObject.h:53
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:78
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
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:3072
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2790
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2982
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3082
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2992
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3061
Sequenceable collection abstract base class.
Int_t LastIndex() const
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Bool_t IsNull() const
Definition TString.h:414
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
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1286
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:857
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:848
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1677
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3986
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4271
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1083
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1550
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1869
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:1410
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1093
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:1308
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:865
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2501
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:946
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1807
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2046
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:2848
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:883
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1560
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1661
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:899
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1044
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:745
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2032
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
std::ostream & Info()
Definition hadd.cxx:171
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#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
@ kWarning
Warnings about likely unexpected behavior.
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:235
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:230
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:231
std::string InsertStd(const char *tname)
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h:255
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
bool IsUniquePtr(std::string_view name)
Definition TClassEdit.h:229
@ kDropStlDefault
Definition TClassEdit.h:83
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:135
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h: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()