Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include "llvm/IR/GlobalValue.h"
119#include "llvm/IR/Module.h"
120
121#include "llvm/Support/DynamicLibrary.h"
122#include "llvm/Support/raw_ostream.h"
123#include "llvm/Support/Path.h"
124#include "llvm/Support/Process.h"
125#include "llvm/Object/ELFObjectFile.h"
126#include "llvm/Object/ObjectFile.h"
127#include "llvm/Object/SymbolicFile.h"
128#include "llvm/Support/FileSystem.h"
129
130#include <algorithm>
131#include <iostream>
132#include <cassert>
133#include <map>
134#include <set>
135#include <stdexcept>
136#include <stdint.h>
137#include <fstream>
138#include <sstream>
139#include <string>
140#include <tuple>
141#include <typeinfo>
142#include <unordered_map>
143#include <unordered_set>
144#include <utility>
145#include <vector>
146#include <functional>
147#include <optional>
148
149#ifndef R__WIN32
150#include <cxxabi.h>
151#define R__DLLEXPORT __attribute__ ((visibility ("default")))
152#include <sys/stat.h>
153#endif
154#include <limits.h>
155#include <stdio.h>
156
157#ifdef __APPLE__
158#include <dlfcn.h>
159#include <mach-o/dyld.h>
160#include <mach-o/loader.h>
161#endif // __APPLE__
162
163#ifdef R__UNIX
164#include <dlfcn.h>
165#endif
166
167#if defined(R__LINUX) || defined(R__FBSD)
168# ifndef _GNU_SOURCE
169# define _GNU_SOURCE
170# endif
171# include <link.h> // dl_iterate_phdr()
172#endif
173
174#if defined(__CYGWIN__)
175#include <sys/cygwin.h>
176#define HMODULE void *
177extern "C" {
178 __declspec(dllimport) void * __stdcall GetCurrentProcess();
179 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
180 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
181}
182#endif
183
184// Fragment copied from LLVM's raw_ostream.cpp
185#if defined(_MSC_VER)
186#ifndef STDIN_FILENO
187# define STDIN_FILENO 0
188#endif
189#ifndef STDOUT_FILENO
190# define STDOUT_FILENO 1
191#endif
192#ifndef STDERR_FILENO
193# define STDERR_FILENO 2
194#endif
195#ifndef R__WIN32
196//#if defined(HAVE_UNISTD_H)
197# include <unistd.h>
198//#endif
199#else
200#include "Windows4Root.h"
201#include <Psapi.h>
202#include <direct.h>
203#undef GetModuleFileName
204#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
205#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
206#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
207#define dlclose(library) ::FreeLibrary((HMODULE)library)
208#define R__DLLEXPORT __declspec(dllexport)
209#endif
210#endif
211
212//______________________________________________________________________________
213// These functions are helpers for debugging issues with non-LLVMDEV builds.
214//
215R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
216 return D->getDeclContext();
217}
218R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
219 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
220}
221R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::RecordDecl>(DC);
223}
224R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
225 return DC->dumpDeclContext();
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
228 return D->dump();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
231 return FD->dump();
232}
234 return ((clang::Decl*)D)->dump();
235}
237 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
238 std::string name;
239 {
240 llvm::raw_string_ostream OS(name);
241 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
242 true /*Qualified*/);
243 }
244 printf("%s\n", name.c_str());
245 }
246}
247//______________________________________________________________________________
248// These functions are helpers for testing issues directly rather than
249// relying on side effects.
250// This is used for the test for ROOT-7462/ROOT-6070
252 return D->isInvalidDecl();
253}
256 assert(info && info->IsValid());
257 return info->GetDecl()->isInvalidDecl();
258}
259
260using std::string, std::vector;
261using namespace clang;
262using namespace ROOT;
263
264namespace {
265 static const std::string gInterpreterClassDef = R"ICF(
266#undef ClassDef
267#define ClassDef(name, id) \
268_ClassDefInterp_(name,id,virtual,) \
269static int DeclFileLine() { return __LINE__; }
270#undef ClassDefNV
271#define ClassDefNV(name, id) \
272_ClassDefInterp_(name,id,,) \
273static int DeclFileLine() { return __LINE__; }
274#undef ClassDefOverride
275#define ClassDefOverride(name, id) \
276_ClassDefInterp_(name,id,,override) \
277static int DeclFileLine() { return __LINE__; }
278)ICF";
279
280 static const std::string gNonInterpreterClassDef = R"ICF(
281#define __ROOTCLING__ 1
282#undef ClassDef
283#define ClassDef(name,id) \
284_ClassDefOutline_(name,id,virtual,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefNV
287#define ClassDefNV(name, id)\
288_ClassDefOutline_(name,id,,)\
289static int DeclFileLine() { return __LINE__; }
290#undef ClassDefOverride
291#define ClassDefOverride(name, id)\
292_ClassDefOutline_(name,id,,override)\
293static int DeclFileLine() { return __LINE__; }
294)ICF";
295
296// The macros below use ::Error, so let's ensure it is included
297 static const std::string gClassDefInterpMacro = R"ICF(
298#include "TError.h"
299
300#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
301private: \
302public: \
303 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
304 static const char *Class_Name() { return #name; } \
305 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
306 static Version_t Class_Version() { return id; } \
307 static TClass *Dictionary() { return 0; } \
308 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
309 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
310 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
311 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
312 static const char *DeclFileName() { return __FILE__; } \
313 static int ImplFileLine() { return 0; } \
314 static const char *ImplFileName() { return __FILE__; }
315)ICF";
316}
318
319// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
320// ROOT (which uses rtti)
321
322////////////////////////////////////////////////////////////////////////////////
323/// Print a StackTrace!
324
325extern "C"
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load a library.
332
333extern "C" int TCling__LoadLibrary(const char *library)
334{
335 return gSystem->Load(library, "", false);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
340
341extern "C" void TCling__RestoreInterpreterMutex(void *delta)
342{
343 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
348/// which is extracted by error messages we get from callback from cling. Return true
349/// when the missing library was autoloaded.
350
351extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
352{
353 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Reset the interpreter lock to the state it had before interpreter-related
358/// calls happened.
359
361{
362 return ((TCling*)gCling)->RewindInterpreterMutex();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Lock the interpreter.
367
369{
370 if (gInterpreterMutex) {
372 }
373 return nullptr;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Unlock the interpreter.
378
380{
381 if (gInterpreterMutex) {
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
388
389static void TCling__UpdateClassInfo(const NamedDecl* TD)
390{
391 static Bool_t entered = kFALSE;
392 static vector<const NamedDecl*> updateList;
393 Bool_t topLevel;
394
395 if (entered) topLevel = kFALSE;
396 else {
397 entered = kTRUE;
398 topLevel = kTRUE;
399 }
400 if (topLevel) {
401 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
402 } else {
403 // If we are called indirectly from within another call to
404 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
405 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
406 // This allows for the dictionary to be fully populated when we actually
407 // update the TClass object. The updating of the TClass sometimes
408 // (STL containers and when there is an emulated class) forces the building
409 // of the TClass object's real data (which needs the dictionary info).
410 updateList.push_back(TD);
411 }
412 if (topLevel) {
413 while (!updateList.empty()) {
414 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
415 updateList.pop_back();
416 }
417 entered = kFALSE;
418 }
419}
420
421void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
422 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
423 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
424 // Add the constants to the enum type.
425 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
426 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
427 // Get name of the enum type.
428 std::string constbuf;
429 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
430 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
431 llvm::raw_string_ostream stream(constbuf);
432 // Don't trigger fopen of the source file to count lines:
433 Policy.AnonymousTagLocations = false;
434 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
435 }
436 const char* constantName = constbuf.c_str();
437
438 // Get value of the constant.
440 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
441 if (valAPSInt.isSigned()) {
442 value = valAPSInt.getSExtValue();
443 } else {
444 value = valAPSInt.getZExtValue();
445 }
446
447 // Create the TEnumConstant or update it if existing
448 TEnumConstant* enumConstant = nullptr;
449 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
450 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
451 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
452 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
453 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
454 } else {
455 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
456 }
457
458 // Add the global constants to the list of Globals.
459 if (!cl) {
460 TCollection* globals = gROOT->GetListOfGlobals(false);
461 if (!globals->FindObject(constantName)) {
462 globals->Add(enumConstant);
463 }
464 }
465 }
466 }
467}
468
469TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
470{
471 // Handle new enum declaration for either global and nested enums.
472
473 // Create the enum type.
474 TEnum* enumType = nullptr;
475 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
476 std::string buf;
477 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
478 // Get name of the enum type.
479 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
480 llvm::raw_string_ostream stream(buf);
481 // Don't trigger fopen of the source file to count lines:
482 Policy.AnonymousTagLocations = false;
483 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
484 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
485 }
486 if (buf.empty()) {
487 return nullptr;
488 }
489 const char* name = buf.c_str();
490 enumType = new TEnum(name, VD, cl);
491 UpdateEnumConstants(enumType, cl);
492
493 return enumType;
494}
495
496void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
497 // Handle new declaration.
498 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
499
500 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
501
502 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
503 && !dyn_cast<clang::RecordDecl>(D)) return;
504
505 if (isa<clang::FunctionDecl>(D->getDeclContext())
506 || isa<clang::TagDecl>(D->getDeclContext()))
507 return;
508
509 // Don't list templates.
510 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
511 if (RD->getDescribedClassTemplate())
512 return;
513 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
514 if (FD->getDescribedFunctionTemplate())
515 return;
516 }
517
518 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
519 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
521 }
522 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
523
524 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
525 // Mostly just for EnumDecl (the other TagDecl are handled
526 // by the 'RecordDecl' if statement.
528 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
530 }
531
532 // We care about declarations on the global scope.
533 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
534 return;
535
536 // Enums are lazyly created, thus we don not need to handle them here.
537 if (isa<EnumDecl>(ND))
538 return;
539
540 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
541 // scope.
542 if (!(isa<VarDecl>(ND)))
543 return;
544
545 // Skip if already in the list.
546 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
547 return;
548
549 // Put the global constants and global enums in the corresponding lists.
550 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
552 cast<ValueDecl>(ND), nullptr)));
553 }
554}
555
556extern "C"
558{
559 // We are sure in this context of the type of the interpreter
560 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
561}
562
563extern "C"
564void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
565 ((TCling*)gCling)->UpdateListsOnCommitted(T);
566}
567
568extern "C"
569void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
570 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
571}
572
573extern "C"
574void TCling__InvalidateGlobal(const clang::Decl *D) {
575 ((TCling*)gCling)->InvalidateGlobal(D);
576}
577
578extern "C"
579void TCling__TransactionRollback(const cling::Transaction &T) {
580 ((TCling*)gCling)->TransactionRollback(T);
581}
582
583extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
584 const char* canonicalName) {
585 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
586}
587
588extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
589{
590 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
591}
592
593extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
594 const char* canonicalName) {
595 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
596}
597
598
599extern "C"
600TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
601 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
602}
603
604extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
605 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
606}
607
608extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
609 const char* argv[])
610{
611 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
612
613 return tcling;
614}
615
617{
618 delete interp;
619}
620
621// Load library containing specified class. Returns 0 in case of error
622// and 1 in case if success.
623extern "C" int TCling__AutoLoadCallback(const char* className)
624{
625 return ((TCling*)gCling)->AutoLoad(className);
626}
627
628extern "C" int TCling__AutoParseCallback(const char* className)
629{
630 return ((TCling*)gCling)->AutoParse(className);
631}
632
633extern "C" const char* TCling__GetClassSharedLibs(const char* className)
634{
635 return ((TCling*)gCling)->GetClassSharedLibs(className);
636}
637
638// Returns 0 for failure 1 for success
639extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
640{
641 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
642}
643
644extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
645{
646 string file(fileName);
647 string opt(options);
648 return gSystem->CompileMacro(file.c_str(), opt.c_str());
649}
650
651extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
652 string &args, string &io, string &fname)
653{
654 string file(fileName);
655 TString f, amode, arguments, aclicio;
656 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
657 mode = amode.Data(); args = arguments.Data();
658 io = aclicio.Data(); fname = f.Data();
659}
660
661//______________________________________________________________________________
662//
663//
664//
665
666#ifdef R__WIN32
667extern "C" {
668 char *__unDName(char *demangled, const char *mangled, int out_len,
669 void * (* pAlloc )(size_t), void (* pFree )(void *),
670 unsigned short int flags);
671}
672#endif
673
674////////////////////////////////////////////////////////////////////////////////
675/// Find a template decl within N nested namespaces, 0<=N<inf
676/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
677/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
678/// Returns nullptr in case of error
679
680static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
681{
682 using namespace clang;
683 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
684 return FindTemplateInNamespace(*nsd->decls_begin());
685 }
686
687 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
688 return ctd;
689 }
690
691 return nullptr; // something went wrong.
692}
693
694//______________________________________________________________________________
695//
696//
697//
698
699int TCling_GenerateDictionary(const std::vector<std::string> &classes,
700 const std::vector<std::string> &headers,
701 const std::vector<std::string> &fwdDecls,
702 const std::vector<std::string> &unknown)
703{
704 //This function automatically creates the "LinkDef.h" file for templated
705 //classes then executes CompileMacro on it.
706 //The name of the file depends on the class name, and it's not generated again
707 //if the file exist.
708 if (classes.empty()) {
709 return 0;
710 }
711 // Use the name of the first class as the main name.
712 const std::string& className = classes[0];
713 //(0) prepare file name
714 TString fileName = "AutoDict_";
715 std::string::const_iterator sIt;
716 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
717 if (*sIt == '<' || *sIt == '>' ||
718 *sIt == ' ' || *sIt == '*' ||
719 *sIt == ',' || *sIt == '&' ||
720 *sIt == ':') {
721 fileName += '_';
722 }
723 else {
724 fileName += *sIt;
725 }
726 }
727 if (classes.size() > 1) {
728 Int_t chk = 0;
729 std::vector<std::string>::const_iterator it = classes.begin();
730 while ((++it) != classes.end()) {
731 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
732 chk = chk * 3 + it->at(cursor);
733 }
734 }
735 fileName += TString::Format("_%u", chk);
736 }
737 fileName += ".cxx";
738 if (gSystem->AccessPathName(fileName) != 0) {
739 //file does not exist
740 //(1) prepare file data
741 // If STL, also request iterators' operators.
742 // vector is special: we need to check whether
743 // vector::iterator is a typedef to pointer or a
744 // class.
745 static const std::set<std::string> sSTLTypes {
746 "vector","list","forward_list","deque","map","unordered_map","multimap",
747 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
748 "queue","priority_queue","stack","iterator"};
749 std::vector<std::string>::const_iterator it;
750 std::string fileContent("");
751 for (it = headers.begin(); it != headers.end(); ++it) {
752 fileContent += "#include \"" + *it + "\"\n";
753 }
754 for (it = unknown.begin(); it != unknown.end(); ++it) {
755 TClass* cl = TClass::GetClass(it->c_str());
756 if (cl && cl->GetDeclFileName()) {
757 TString header = gSystem->BaseName(cl->GetDeclFileName());
759 TString dirbase(gSystem->BaseName(dir));
760 while (dirbase.Length() && dirbase != "."
761 && dirbase != "include" && dirbase != "inc"
762 && dirbase != "prec_stl") {
763 gSystem->PrependPathName(dirbase, header);
764 dir = gSystem->GetDirName(dir);
765 }
766 fileContent += TString("#include \"") + header + "\"\n";
767 }
768 }
769 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
770 fileContent += "class " + *it + ";\n";
771 }
772 fileContent += "#ifdef __CLING__ \n";
773 fileContent += "#pragma link C++ nestedclasses;\n";
774 fileContent += "#pragma link C++ nestedtypedefs;\n";
775 for (it = classes.begin(); it != classes.end(); ++it) {
776 std::string n(*it);
777 size_t posTemplate = n.find('<');
778 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
779 if (posTemplate != std::string::npos) {
780 n.erase(posTemplate, std::string::npos);
781 if (n.compare(0, 5, "std::") == 0) {
782 n.erase(0, 5);
783 }
784 iSTLType = sSTLTypes.find(n);
785 }
786 fileContent += "#pragma link C++ class ";
787 fileContent += *it + "+;\n" ;
788 fileContent += "#pragma link C++ class ";
789 if (iSTLType != sSTLTypes.end()) {
790 // STL class; we cannot (and don't need to) store iterators;
791 // their shadow and the compiler's version don't agree. So
792 // don't ask for the '+'
793 fileContent += *it + "::*;\n" ;
794 }
795 else {
796 // Not an STL class; we need to allow the I/O of contained
797 // classes (now that we have a dictionary for them).
798 fileContent += *it + "::*+;\n" ;
799 }
800 }
801 fileContent += "#endif\n";
802 //end(1)
803 //(2) prepare the file
804 FILE* filePointer;
805 filePointer = fopen(fileName, "w");
806 if (filePointer == nullptr) {
807 //can't open a file
808 return 1;
809 }
810 //end(2)
811 //write data into the file
812 fprintf(filePointer, "%s", fileContent.c_str());
813 fclose(filePointer);
814 }
815 //(3) checking if we can compile a macro, if not then cleaning
816 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
817 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
818 Int_t ret = gSystem->CompileMacro(fileName, "k");
819 gErrorIgnoreLevel = oldErrorIgnoreLevel;
820 if (ret == 0) { //can't compile a macro
821 return 2;
822 }
823 //end(3)
824 return 0;
825}
826
827int TCling_GenerateDictionary(const std::string& className,
828 const std::vector<std::string> &headers,
829 const std::vector<std::string> &fwdDecls,
830 const std::vector<std::string> &unknown)
831{
832 //This function automatically creates the "LinkDef.h" file for templated
833 //classes then executes CompileMacro on it.
834 //The name of the file depends on the class name, and it's not generated again
835 //if the file exist.
836 std::vector<std::string> classes;
837 classes.push_back(className);
838 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
839}
840
841//______________________________________________________________________________
842//
843//
844//
845
846// It is a "fantom" method to synchronize user keyboard input
847// and ROOT prompt line (for WIN32)
848const char* fantomline = "TRint::EndOfLineAction();";
849
850//______________________________________________________________________________
851//
852//
853//
854
855void* TCling::fgSetOfSpecials = nullptr;
856
857//______________________________________________________________________________
858//
859// llvm error handler through exceptions; see also cling/UserInterface
860//
861namespace {
862 // Handle fatal llvm errors by throwing an exception.
863 // Yes, throwing exceptions in error handlers is bad.
864 // Doing nothing is pretty terrible, too.
865 void exceptionErrorHandler(void * /*user_data*/,
866 const char *reason,
867 bool /*gen_crash_diag*/) {
868 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
869 }
870}
871
872//______________________________________________________________________________
873//
874//
875//
876
877////////////////////////////////////////////////////////////////////////////////
878
879namespace{
880 // An instance of this class causes the diagnostics of clang to be suppressed
881 // during its lifetime
882 class clangDiagSuppr {
883 public:
884 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
885 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
886 fDiagEngine.setIgnoreAllWarnings(true);
887 }
888
889 ~clangDiagSuppr() {
890 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
891 }
892 private:
893 clang::DiagnosticsEngine& fDiagEngine;
894 bool fOldDiagValue;
895 };
896
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Allow calling autoparsing from TMetaUtils
902{
903 return gCling->AutoParse(cname);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Try hard to avoid looking up in the Cling database as this could enduce
908/// an unwanted autoparsing.
909
910bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
911 std::string &result)
912{
913 result.clear();
914
915 unsigned long offset = 0;
916 if (strncmp(tname.c_str(), "const ", 6) == 0) {
917 offset = 6;
918 }
919 unsigned long end = tname.length();
920 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
921 if ( tname[end-1]==']' ) {
922 --end;
923 while ( end && tname[end-1]!='[' ) --end;
924 }
925 --end;
926 }
927 std::string innerbuf;
928 const char *inner;
929 if (end != tname.length()) {
930 innerbuf = tname.substr(offset,end-offset);
931 inner = innerbuf.c_str();
932 } else {
933 inner = tname.c_str()+offset;
934 }
935
936 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
937 if (gROOT->GetListOfClasses()->FindObject(inner)
938 || TClassTable::Check(inner,result) ) {
939 // This is a known class.
940 return true;
941 }
942
943 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
944 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
945 if (type) {
946 // This is a raw type and an already loaded typedef.
947 const char *newname = type->GetFullTypeName();
948 if (type->GetType() == kLong64_t) {
949 newname = "Long64_t";
950 } else if (type->GetType() == kULong64_t) {
951 newname = "ULong64_t";
952 }
953 if (strcmp(inner,newname) == 0) {
954 return true;
955 }
956 if (offset) result = "const ";
957 result += newname;
958 if ( end != tname.length() ) {
959 result += tname.substr(end,tname.length()-end);
960 }
961 if (result == tname) result.clear();
962 return true;
963 }
964
965 // Check if the name is an enumerator
966 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
967 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
968 {
969 // We have a scope
970 // All of this C gymnastic is to avoid allocations on the heap
971 const auto enName = lastPos;
972 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
973 char *scopeName = new char[scopeNameSize + 1];
974 strncpy(scopeName, inner, scopeNameSize);
975 scopeName[scopeNameSize] = '\0';
976 // Check if the scope is in the list of classes
977 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
978 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
979 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
980 }
981 // It may still be in one of the loaded protoclasses
982 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
983 auto listOfEnums = scope->GetListOfEnums();
984 if (listOfEnums) { // it could be null: no enumerators in the protoclass
985 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
986 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
987 }
988 }
989 delete [] scopeName;
990 } else
991 {
992 // We don't have any scope: this could only be a global enum
993 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
994 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
995 }
996
997 if (gCling->GetClassSharedLibs(inner))
998 {
999 // This is a class name.
1000 return true;
1001 }
1002
1003 return false;
1004}
1005
1006////////////////////////////////////////////////////////////////////////////////
1007
1009{
1010 fContent.reserve(size);
1011}
1012
1013////////////////////////////////////////////////////////////////////////////////
1014
1016{
1017 return fContent.c_str();
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Append string to the storage if not added already.
1022
1023inline bool TCling::TUniqueString::Append(const std::string& str)
1024{
1025 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1026 if (notPresent){
1027 fContent+=str;
1028 }
1029 return notPresent;
1030}
1031
1032std::string TCling::ToString(const char* type, void* obj)
1033{
1034 return fInterpreter->toString(type, obj);
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038///\returns true if the module was loaded.
1039static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1040{
1041 // When starting up ROOT, cling would load all modulemap files on the include
1042 // paths. However, in a ROOT session, it is very common to run aclic which
1043 // will invoke rootcling and possibly produce a modulemap and a module in
1044 // the current folder.
1045 //
1046 // Before failing, try loading the modulemap in the current folder and try
1047 // loading the requested module from it.
1048 std::string currentDir = gSystem->WorkingDirectory();
1049 assert(!currentDir.empty());
1051 if (gDebug > 2)
1052 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1053 ModuleName.c_str());
1054
1055 return interp.loadModule(ModuleName, /*Complain=*/true);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Loads the C++ modules that we require to run any ROOT program. This is just
1060/// supposed to make a C++ module from a modulemap available to the interpreter.
1061static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1062{
1063 for (const auto &modName : modules)
1064 LoadModule(modName, interp);
1065}
1066
1067static bool IsFromRootCling() {
1068 // rootcling also uses TCling for generating the dictionary ROOT files.
1069 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1070 return foundSymbol;
1071}
1072
1073/// Checks if there is an ASTFile on disk for the given module \c M.
1074static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1075{
1076 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1077
1078 std::string ModuleFileName;
1079 if (!HSOpts.PrebuiltModulePaths.empty())
1080 // Load the module from *only* in the prebuilt module path.
1081 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1082 if (FullFileName)
1083 *FullFileName = ModuleFileName;
1084
1085 return !ModuleFileName.empty();
1086}
1087
1088static bool HaveFullGlobalModuleIndex = false;
1089static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1090{
1091 CompilerInstance &CI = *interp.getCI();
1092 Preprocessor &PP = CI.getPreprocessor();
1093 auto ModuleManager = CI.getASTReader();
1094 assert(ModuleManager);
1095 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1096 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1097 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1098 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1099 if (ModuleIndexPath.empty())
1100 return nullptr;
1101 // Get an existing global index. This loads it if not already loaded.
1102 ModuleManager->resetForReload();
1103 ModuleManager->loadGlobalIndex();
1104 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1105
1106 // For finding modules needing to be imported for fixit messages,
1107 // we need to make the global index cover all modules, so we do that here.
1108 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1109 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1110 bool RecreateIndex = false;
1111 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1112 Module *TheModule = I->second;
1113 // We want the index only of the prebuilt modules.
1114 if (!HasASTFileOnDisk(TheModule, PP))
1115 continue;
1116 LoadModule(TheModule->Name, interp);
1117 RecreateIndex = true;
1118 }
1119 if (RecreateIndex) {
1120 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1121 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1122
1123 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1124 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1125 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1126 TraverseDecl(TU);
1127 }
1128 bool VisitNamedDecl(NamedDecl *ND) {
1129 if (!ND->isFromASTFile())
1130 return true;
1131 if (!ND->getIdentifier())
1132 return true;
1133
1134 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1135 return true;
1136
1137 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1138 if (TD->isCompleteDefinition())
1139 Register(TD);
1140 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1141 Register(NSD, /*AddSingleEntry=*/ false);
1142 }
1143 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1144 Register(TND);
1145 // FIXME: Add the rest...
1146 return true; // continue decending
1147 }
1148 private:
1149 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1150 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1151 assert(ND->isFromASTFile());
1152 // FIXME: All decls should have an owning module once rootcling
1153 // updates its generated decls from within the LookupHelper & co.
1154 if (!ND->hasOwningModule()) {
1155#ifndef NDEBUG
1156 SourceManager &SM = ND->getASTContext().getSourceManager();
1157 SourceLocation Loc = ND->getLocation();
1158 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1159 (void)FE;
1160 assert(FE->getName().contains("input_line_"));
1161#endif
1162 return;
1163 }
1164
1165 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1166 assert(OwningModule);
1167 assert(!ND->getName().empty() && "Empty name");
1168 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1169 return;
1170 // FIXME: The FileEntry in not stable to serialize.
1171 // FIXME: We might end up with many times with the same module.
1172 // FIXME: We might end up two modules containing a definition.
1173 // FIXME: What do we do if no definition is found.
1174 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1175 }
1176 };
1177 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1178
1179 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1180 CI.getPCHContainerReader(),
1181 ModuleIndexPath,
1182 &IDs));
1183 ModuleManager->resetForReload();
1184 ModuleManager->loadGlobalIndex();
1185 GlobalIndex = ModuleManager->getGlobalIndex();
1186 }
1188 }
1189 return GlobalIndex;
1190}
1191
1192static void RegisterCxxModules(cling::Interpreter &clingInterp)
1193{
1194 if (!clingInterp.getCI()->getLangOpts().Modules)
1195 return;
1196
1197 // Loading of a module might deserialize.
1198 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1199
1200 // Setup core C++ modules if we have any to setup.
1201
1202 // Load libc and stl first.
1203 // Load vcruntime module for windows
1204#ifdef R__WIN32
1205 LoadModule("vcruntime", clingInterp);
1206 LoadModule("services", clingInterp);
1207#endif
1208
1209#ifdef R__MACOSX
1210 LoadModule("Darwin", clingInterp);
1211#else
1212 LoadModule("libc", clingInterp);
1213#endif
1214 LoadModule("std", clingInterp);
1215
1216 LoadModule("_Builtin_intrinsics", clingInterp);
1217
1218 // Load core modules
1219 // This should be vector in order to be able to pass it to LoadModules
1220 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1221 "ROOT_Config",
1222 "ROOT_Rtypes",
1223 "ROOT_Foundation_Stage1_NoRTTI",
1224 "Core",
1225 "Rint",
1226 "RIO"};
1227
1228 LoadModules(CoreModules, clingInterp);
1229
1230 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1231 if (!IsFromRootCling()) {
1232 std::vector<std::string> CommonModules = {"MathCore"};
1233 LoadModules(CommonModules, clingInterp);
1234
1235 // These modules should not be preloaded but they fix issues.
1236 // FIXME: Hist is not a core module but is very entangled to MathCore and
1237 // causes issues.
1238 std::vector<std::string> FIXMEModules = {"Hist"};
1239 clang::CompilerInstance &CI = *clingInterp.getCI();
1240 clang::Preprocessor &PP = CI.getPreprocessor();
1241 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1242 if (MMap.findModule("RInterface"))
1243 FIXMEModules.push_back("RInterface");
1244
1245 LoadModules(FIXMEModules, clingInterp);
1246
1247 GlobalModuleIndex *GlobalIndex = nullptr;
1248 loadGlobalModuleIndex(clingInterp);
1249 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1250 // We should investigate how to suppress it completely.
1251 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1252
1253 llvm::StringSet<> KnownModuleFileNames;
1254 if (GlobalIndex)
1255 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1256
1257 std::vector<std::string> PendingModules;
1258 PendingModules.reserve(256);
1259 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1260 clang::Module *M = I->second;
1261 assert(M);
1262
1263 // We want to load only already created modules.
1264 std::string FullASTFilePath;
1265 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1266 continue;
1267
1268 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1269 continue;
1270
1271 if (M->IsUnimportable)
1272 continue;
1273
1274 if (GlobalIndex)
1275 LoadModule(M->Name, clingInterp);
1276 else {
1277 // FIXME: We may be able to remove those checks as cling::loadModule
1278 // checks if a module was alredy loaded.
1279 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1280 continue; // This is a core module which was already loaded.
1281
1282 // Load system modules now and delay the other modules after we have
1283 // loaded all system ones.
1284 if (M->IsSystem)
1285 LoadModule(M->Name, clingInterp);
1286 else
1287 PendingModules.push_back(M->Name);
1288 }
1289 }
1290 LoadModules(PendingModules, clingInterp);
1291 }
1292
1293 // Check that the gROOT macro was exported by any core module.
1294 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1295
1296 // `ERROR` and `PI` are from loading R related modules, which conflict with
1297 // user's code.
1298 clingInterp.declare(R"CODE(
1299#ifdef PI
1300# undef PI
1301#endif
1302#ifdef ERROR
1303# undef ERROR
1304#endif
1305 )CODE");
1306}
1307
1308static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1309{
1310 std::string PreIncludes;
1311 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1312
1313 // For the list to also include string, we have to include it now.
1314 // rootcling does parts already if needed, e.g. genreflex does not want using
1315 // namespace std.
1316 if (IsFromRootCling()) {
1317 PreIncludes += "#include \"RtypesCore.h\"\n";
1318 } else {
1319 if (!hasCxxModules)
1320 PreIncludes += "#include \"Rtypes.h\"\n";
1321
1322 PreIncludes += gClassDefInterpMacro + "\n"
1323 + gInterpreterClassDef + "\n"
1324 "#undef ClassImp\n"
1325 "#define ClassImp(X);\n";
1326 }
1327 if (!hasCxxModules)
1328 PreIncludes += "#include <string>\n";
1329
1330 // We must include it even when we have modules because it is marked as
1331 // textual in the modulemap due to the nature of the assert header.
1332#ifndef R__WIN32
1333 PreIncludes += "#include <cassert>\n";
1334#endif
1335 PreIncludes += "using namespace std;\n";
1336 clingInterp.declare(PreIncludes);
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Initialize the cling interpreter interface.
1341/// \param name name for TInterpreter
1342/// \param title title for TInterpreter
1343/// \param argv - array of arguments passed to the cling::Interpreter constructor
1344/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1345
1346TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1347: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1348 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr),
1349 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1351{
1352 fPrompt[0] = 0;
1353 const bool fromRootCling = IsFromRootCling();
1354
1355 fCxxModulesEnabled = false;
1356#ifdef R__USE_CXXMODULES
1357 fCxxModulesEnabled = true;
1358#endif
1359
1360 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1361
1362 fTemporaries = new std::vector<cling::Value>();
1363
1364 std::vector<std::string> clingArgsStorage;
1365 clingArgsStorage.push_back("cling4root");
1366 for (const char* const* arg = argv; *arg; ++arg)
1367 clingArgsStorage.push_back(*arg);
1368
1369 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1370 if (!fromRootCling) {
1372
1373 // Add -I early so ASTReader can find the headers.
1374 std::string interpInclude(TROOT::GetEtcDir().Data());
1375 clingArgsStorage.push_back("-I" + interpInclude);
1376
1377 // Add include path to etc/cling.
1378 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1379
1380 // Add include path to etc/cling.
1381 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1382
1383 // Add the root include directory and etc/ to list searched by default.
1384 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1385
1386 // Add the current path to the include path
1387 // TCling::AddIncludePath(".");
1388
1389 // Attach the PCH (unless we have C++ modules enabled which provide the
1390 // same functionality).
1391 if (!fCxxModulesEnabled) {
1392 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1393 if (gSystem->Getenv("ROOT_PCH")) {
1394 pchFilename = gSystem->Getenv("ROOT_PCH");
1395 }
1396
1397 clingArgsStorage.push_back("-include-pch");
1398 clingArgsStorage.push_back(pchFilename);
1399 }
1400
1401 clingArgsStorage.push_back("-Wno-undefined-inline");
1402 clingArgsStorage.push_back("-fsigned-char");
1403 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1404 // See the GitHub issues #9809 and #9944
1405 // TODO: to be reviewed after the upgrade of LLVM & Clang
1406#ifndef _MSC_VER
1407 clingArgsStorage.push_back("-O1");
1408 // Disable optimized register allocation which is turned on automatically
1409 // by -O1, but seems to require -O2 to not explode in run time.
1410 clingArgsStorage.push_back("-mllvm");
1411 clingArgsStorage.push_back("-optimize-regalloc=0");
1412#endif
1413 }
1414
1415 // Process externally passed arguments if present.
1416 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1417 if (EnvOpt.has_value()) {
1418 StringRef Env(*EnvOpt);
1419 while (!Env.empty()) {
1420 StringRef Arg;
1421 std::tie(Arg, Env) = Env.split(' ');
1422 clingArgsStorage.push_back(Arg.str());
1423 }
1424 }
1425
1426 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1427 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1428 if (EnvOpt.has_value()) {
1429 StringRef Env(*EnvOpt);
1430 while (!Env.empty()) {
1431 StringRef Arg;
1432 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1433 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1434 Paths.push_back(Arg.str());
1435 }
1436 }
1437 };
1438
1439 if (fCxxModulesEnabled) {
1440 std::vector<std::string> Paths;
1441 // ROOT usually knows better where its libraries are. This way we can
1442 // discover modules without having to should thisroot.sh and should fix
1443 // gnuinstall.
1444 Paths.push_back(TROOT::GetSharedLibDir().Data());
1445 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1446 std::string EnvVarPath;
1447 for (const std::string& P : Paths)
1449 // FIXME: We should make cling -fprebuilt-module-path work.
1450 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1451 }
1452
1453 // FIXME: This only will enable frontend timing reports.
1454 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1455 if (EnvOpt.has_value())
1456 clingArgsStorage.push_back("-ftime-report");
1457
1458 // Add the overlay file. Note that we cannot factor it out for both root
1459 // and rootcling because rootcling activates modules only if -cxxmodule
1460 // flag is passed.
1461 if (fCxxModulesEnabled && !fromRootCling) {
1462 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1463 std::vector<std::string> ModuleMaps;
1464 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1465 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1466 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1467
1468 std::string cwd = gSystem->WorkingDirectory();
1469 // Give highest precedence of the modulemap in the cwd if any.
1470 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1471 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1472
1473 for (const std::string& M : ModuleMaps)
1474 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1475
1476 std::string ModulesCachePath;
1477 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1478 if (EnvOpt.has_value()){
1479 StringRef Env(*EnvOpt);
1480 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1481 ModulesCachePath = Env.str();
1482 } else {
1483 ModulesCachePath = TROOT::GetSharedLibDir();
1484 }
1485
1486 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1487 }
1488
1489 std::vector<const char*> interpArgs;
1490 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1491 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1492 interpArgs.push_back(iArg->c_str());
1493
1494 // Activate C++ modules support. If we are running within rootcling, it's up
1495 // to rootcling to set this flag depending on whether it wants to produce
1496 // C++ modules.
1497 TString vfsArg;
1498 if (fCxxModulesEnabled) {
1499 if (!fromRootCling) {
1500 // We only set this flag, rest is done by the CIFactory.
1501 interpArgs.push_back("-fmodules");
1502 interpArgs.push_back("-fno-implicit-module-maps");
1503 // We should never build modules during runtime, so let's enable the
1504 // module build remarks from clang to make it easier to spot when we do
1505 // this by accident.
1506 interpArgs.push_back("-Rmodule-build");
1507 }
1508 // ROOT implements its AutoLoading upon module's link directives. We
1509 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1510 // facilities use the link directive to dynamically load the relevant
1511 // library. So, we need to suppress clang's default autolink behavior.
1512 interpArgs.push_back("-fno-autolink");
1513 }
1514
1515#ifdef R__FAST_MATH
1516 // Same setting as in rootcling_impl.cxx.
1517 interpArgs.push_back("-ffast-math");
1518#endif
1519
1520 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1521 // Add statically injected extra arguments, usually coming from rootcling.
1522 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1523 extraArgs && *extraArgs; ++extraArgs) {
1524 if (!strcmp(*extraArgs, "-resource-dir")) {
1525 // Take the next arg as the llvm resource directory.
1526 llvmResourceDir = *(++extraArgs);
1527 } else {
1528 interpArgs.push_back(*extraArgs);
1529 }
1530 }
1531
1532 std::vector<std::string> _empty;
1533 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1534 for (const auto &arg: args)
1535 interpArgs.emplace_back(arg.c_str());
1536
1537 // Add the Rdict module file extension.
1538 cling::Interpreter::ModuleFileExtensions extensions;
1539 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1540 if (!EnvOpt.has_value())
1541 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1542
1543 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1544 &(interpArgs[0]),
1545 llvmResourceDir, extensions,
1546 interpLibHandle);
1547
1548 // Don't check whether modules' files exist.
1549 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1550 DisableValidationForModuleKind::All;
1551
1552 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1553 // to disable spell checking.
1554 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1555
1556 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1557 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1558 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1559 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1560
1561 // We need stream that doesn't close its file descriptor, thus we are not
1562 // using llvm::outs. Keeping file descriptor open we will be able to use
1563 // the results in pipes (Savannah #99234).
1564 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1565 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1566
1569
1570 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1577
1578 // Disallow auto-parsing in rootcling
1579 fIsAutoParsingSuspended = fromRootCling;
1580
1581 ResetAll();
1582
1583 // Enable dynamic lookup
1584 if (!fromRootCling) {
1585 fInterpreter->enableDynamicLookup();
1586 }
1587
1588 // Enable ClinG's DefinitionShadower for ROOT.
1589 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1590 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1591 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1592 // FIXME: We should probably switch to the default printing policy setting
1593 // after adjusting tons of reference files.
1594 Policy.SplitTemplateClosers = true;
1595 // Keep default templare arguments, required for dictionary generation.
1596 Policy.SuppressDefaultTemplateArgs = false;
1597
1598
1599 // Attach cling callbacks last; they might need TROOT::fInterpreter
1600 // and should thus not be triggered during the equivalent of
1601 // TROOT::fInterpreter = new TCling;
1602 std::unique_ptr<TClingCallbacks>
1603 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1604 fClingCallbacks = clingCallbacks.get();
1606 fInterpreter->setCallbacks(std::move(clingCallbacks));
1607
1608 if (!fromRootCling) {
1609 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1610 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1611 // e.g. because of an RPATH build.
1612 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1613 /*prepend=*/true);
1614 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1615 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1616 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1617 };
1618 // Initialize the dyld for AutoloadLibraryGenerator.
1619 DLM.initializeDyld(ShouldPermanentlyIgnore);
1620 }
1621}
1622
1623
1624////////////////////////////////////////////////////////////////////////////////
1625/// Destroy the interpreter interface.
1626
1628{
1629 // ROOT's atexit functions require the interepreter to be available.
1630 // Run them before shutting down.
1631 if (!IsFromRootCling())
1632 GetInterpreterImpl()->runAtExitFuncs();
1633 fIsShuttingDown = true;
1634 delete fMapfile;
1635 delete fRootmapFiles;
1636 delete fTemporaries;
1637 delete fNormalizedCtxt;
1638 delete fLookupHelper;
1639 gCling = nullptr;
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Initialize the interpreter, once TROOT::fInterpreter is set.
1644
1646{
1648
1649 // We are set up. Enable ROOT's AutoLoading.
1650 if (IsFromRootCling())
1651 return;
1652
1653 // Read the rules before enabling the auto loading to not inadvertently
1654 // load the libraries for the classes concerned even-though the user is
1655 // *not* using them.
1656 // Note this call must happen before the first call to LoadLibraryMap.
1657 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1658 TClass::ReadRules(); // Read the default customization rules ...
1659
1661 SetClassAutoLoading(true);
1662}
1663
1665{
1666 fIsShuttingDown = true;
1667 ResetGlobals();
1668}
1669
1670////////////////////////////////////////////////////////////////////////////////
1671/// Helper to initialize TVirtualStreamerInfo's factor early.
1672/// Use static initialization to insure only one TStreamerInfo is created.
1674{
1675 // Use lambda since SetFactory return void.
1676 auto setFactory = []() {
1678 return kTRUE;
1679 };
1680 static bool doneFactory = setFactory();
1681 return doneFactory; // avoid unused variable warning.
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685/// Register Rdict data for future loading by LoadPCM;
1686
1687void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1688{
1689 if (IsFromRootCling())
1690 return;
1691
1692 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1693 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1694 return;
1695 }
1696
1697 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1698 // a link to a non-existent file.
1699 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////
1703/// Tries to load a PCM from TFile; returns true on success.
1704
1706{
1707 auto listOfKeys = pcmFile.GetListOfKeys();
1708
1709 // This is an empty pcm
1710 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1711 ((listOfKeys->GetSize() == 1) && // only one, and
1712 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1713 ))) {
1714 return;
1715 }
1716
1717 TObjArray *protoClasses;
1718 if (gDebug > 1)
1719 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1720
1721 TObjArray *enums;
1722 pcmFile.GetObject("__Enums", enums);
1723 if (enums) {
1724 // Cache the pointers
1725 auto listOfGlobals = gROOT->GetListOfGlobals();
1726 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1727 // Loop on enums and then on enum constants
1728 for (auto selEnum : *enums) {
1729 const char *enumScope = selEnum->GetTitle();
1730 const char *enumName = selEnum->GetName();
1731 if (strcmp(enumScope, "") == 0) {
1732 // This is a global enum and is added to the
1733 // list of enums and its constants to the list of globals
1734 if (!listOfEnums->THashList::FindObject(enumName)) {
1735 ((TEnum *)selEnum)->SetClass(nullptr);
1736 listOfEnums->Add(selEnum);
1737 }
1738 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1739 if (!listOfGlobals->FindObject(enumConstant)) {
1740 listOfGlobals->Add(enumConstant);
1741 }
1742 }
1743 } else {
1744 // This enum is in a namespace. A TClass entry is bootstrapped if
1745 // none exists yet and the enum is added to it
1746 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1747 if (!nsTClassEntry) {
1748 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1749 }
1750 auto listOfEnums = nsTClassEntry->fEnums.load();
1751 if (!listOfEnums) {
1752 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1753 // For this case, the list will be immutable once constructed
1754 // (i.e. in this case, by the end of this routine).
1755 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1756 } else {
1757 // namespaces can have enums added to them
1758 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1759 }
1760 }
1761 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1762 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1763 listOfEnums->Add(selEnum);
1764 }
1765 }
1766 }
1767 enums->Clear();
1768 delete enums;
1769 }
1770
1771 pcmFile.GetObject("__ProtoClasses", protoClasses);
1772
1773 if (protoClasses) {
1774 for (auto obj : *protoClasses) {
1775 TProtoClass *proto = (TProtoClass *)obj;
1777 }
1778 // Now that all TClass-es know how to set them up we can update
1779 // existing TClasses, which might cause the creation of e.g. TBaseClass
1780 // objects which in turn requires the creation of TClasses, that could
1781 // come from the PCH, but maybe later in the loop. Instead of resolving
1782 // a dependency graph the addition to the TClassTable above allows us
1783 // to create these dependent TClasses as needed below.
1784 for (auto proto : *protoClasses) {
1785 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1786 // We have an existing TClass object. It might be emulated
1787 // or interpreted; we now have more information available.
1788 // Make that available.
1789 if (existingCl->GetState() != TClass::kHasTClassInit) {
1790 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1791 if (!dict) {
1792 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1793 } else {
1794 // This will replace the existing TClass.
1795 TClass *ncl = (*dict)();
1796 if (ncl)
1797 ncl->PostLoadCheck();
1798 }
1799 }
1800 }
1801 }
1802
1803 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1804 delete protoClasses;
1805 }
1806
1807 TObjArray *dataTypes;
1808 pcmFile.GetObject("__Typedefs", dataTypes);
1809 if (dataTypes) {
1810 for (auto typedf : *dataTypes)
1811 gROOT->GetListOfTypes()->Add(typedf);
1812 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1813 delete dataTypes;
1814 }
1815}
1816
1817////////////////////////////////////////////////////////////////////////////////
1818/// Tries to load a rdict PCM, issues diagnostics if it fails.
1819
1820void TCling::LoadPCM(std::string pcmFileNameFullPath)
1821{
1822 SuspendAutoLoadingRAII autoloadOff(this);
1823 SuspendAutoParsing autoparseOff(this);
1824 assert(!pcmFileNameFullPath.empty());
1825 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1826
1827 // Easier to work with the ROOT interfaces.
1828 TString pcmFileName = pcmFileNameFullPath;
1829
1830 // Prevent the ROOT-PCMs hitting this during auto-load during
1831 // JITting - which will cause recursive compilation.
1832 // Avoid to call the plugin manager at all.
1834
1836 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1837 if (gDebug > 5) {
1838 gDebug -= 5;
1839 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1840 } else {
1841 gDebug = 0;
1842 }
1843
1844 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1845 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1846
1847 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1848 if (pendingRdict != fPendingRdicts.end()) {
1849 llvm::StringRef pcmContent = pendingRdict->second;
1850 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1851 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1852 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1853
1854 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1855 LoadPCMImpl(pcmMemFile);
1856 // Currently the module file are never unloaded (even if the library is
1857 // unloaded) and, of course, never reloaded.
1858 // Consequently, we must NOT remove the `pendingRdict` from the list
1859 // of pending dictionary, otherwise if a library is unloaded and then
1860 // reload we will be unable to update properly the TClass object
1861 // (because we wont be able to load the rootpcm file by executing the
1862 // above lines)
1863
1864 return;
1865 }
1866
1867 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1868 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1869 pcmFileNameFullPath.data());
1870 if (!fPendingRdicts.empty())
1871 for (const auto &rdict : fPendingRdicts)
1872 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1873 rdict.first.c_str());
1874 return;
1875 }
1876
1877 if (!gROOT->IsRootFile(pcmFileName)) {
1878 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1879 return;
1880 }
1881 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1882 LoadPCMImpl(pcmFile);
1883}
1884
1885//______________________________________________________________________________
1886
1887namespace {
1888 using namespace clang;
1889
1890 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1891 // This class is to be considered an helper for autoparsing.
1892 // It visits the AST and marks all classes (in all of their redeclarations)
1893 // with the setHasExternalLexicalStorage method.
1894 public:
1895 bool VisitRecordDecl(clang::RecordDecl* rcd){
1896 if (gDebug > 2)
1897 Info("ExtLexicalStorageAdder",
1898 "Adding external lexical storage to class %s",
1899 rcd->getNameAsString().c_str());
1900 auto reDeclPtr = rcd->getMostRecentDecl();
1901 do {
1902 reDeclPtr->setHasExternalLexicalStorage();
1903 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1904
1905 return false;
1906 }
1907 };
1908
1909
1910}
1911
1912////////////////////////////////////////////////////////////////////////////////
1913///\returns true if the module map was loaded, false on error or if the map was
1914/// already loaded.
1915bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1916 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1917{
1918 assert(llvm::sys::path::is_absolute(FullPath));
1919 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1920 FileManager &FM = PP.getFileManager();
1921 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1922 // We should look for modulemap files there too.
1923 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1924 HeaderSearch &HS = PP.getHeaderSearchInfo();
1925 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1926 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1927 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1928 if (!pathExists)
1929 HSOpts.AddPrebuiltModulePath(FullPath);
1930 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1931 // because its internal call to getFile has CacheFailure set to true.
1932 // In our case, modulemaps can appear any time due to ACLiC.
1933 // Code copied from HS.lookupModuleMapFile.
1934 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1935 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1936 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1937 /*CacheFailure*/ false)) {
1938 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1939 return true;
1940 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1941 }
1942 }
1943 return false;
1944}
1945
1946////////////////////////////////////////////////////////////////////////////////
1947/// List of dicts that have the PCM information already in the PCH.
1948static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1949 "libRint",
1950 "libThread",
1951 "libRIO",
1952 "libImt",
1953 "libMultiProc",
1954 "libcomplexDict",
1955 "libdequeDict",
1956 "liblistDict",
1957 "libforward_listDict",
1958 "libvectorDict",
1959 "libmapDict",
1960 "libmultimap2Dict",
1961 "libmap2Dict",
1962 "libmultimapDict",
1963 "libsetDict",
1964 "libmultisetDict",
1965 "libunordered_setDict",
1966 "libunordered_multisetDict",
1967 "libunordered_mapDict",
1968 "libunordered_multimapDict",
1969 "libvalarrayDict",
1970 "G__GenVector32",
1971 "G__Smatrix32"};
1972
1973static void PrintDlError(const char *dyLibName, const char *modulename)
1974{
1975#ifdef R__WIN32
1976 char dyLibError[1000];
1977 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1978 dyLibError, sizeof(dyLibError), NULL);
1979#else
1980 const char *dyLibError = dlerror();
1981#endif
1982 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1983 (dyLibError) ? dyLibError : "");
1984}
1985
1986////////////////////////////////////////////////////////////////////////////////
1987// Update all the TClass registered in fClassesToUpdate
1988
1990{
1991 while (!fClassesToUpdate.empty()) {
1992 TClass *oldcl = fClassesToUpdate.back().first;
1993 // If somehow the TClass has already been loaded (maybe it was registered several time),
1994 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1995 // maybe even kForwardDeclared and needs to replaced.
1996 if (oldcl->GetState() != TClass::kHasTClassInit) {
1997 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1998 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1999 fClassesToUpdate.pop_back();
2000 // Calling func could manipulate the list so, let maintain the list
2001 // then call the dictionary function.
2002 TClass *ncl = dict();
2003 if (ncl) ncl->PostLoadCheck();
2004 } else {
2005 fClassesToUpdate.pop_back();
2006 }
2007 }
2008}
2009////////////////////////////////////////////////////////////////////////////////
2010/// Inject the module named "modulename" into cling; load all headers.
2011/// headers is a 0-terminated array of header files to `#include` after
2012/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2013/// entries (or %PATH% on Windows).
2014/// This function gets called by the static initialization of dictionary
2015/// libraries.
2016/// The payload code is injected "as is" in the interpreter.
2017/// The value of 'triggerFunc' is used to find the shared library location.
2018
2019void TCling::RegisterModule(const char* modulename,
2020 const char** headers,
2021 const char** includePaths,
2022 const char* payloadCode,
2023 const char* fwdDeclsCode,
2024 void (*triggerFunc)(),
2025 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2026 const char** classesHeaders,
2027 Bool_t lateRegistration /*=false*/,
2028 Bool_t hasCxxModule /*=false*/)
2029{
2030 const bool fromRootCling = IsFromRootCling();
2031 // We need the dictionary initialization but we don't want to inject the
2032 // declarations into the interpreter, except for those we really need for
2033 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2034 if (fromRootCling) return;
2035
2036 // When we cannot provide a module for the library we should enable header
2037 // parsing. This 'mixed' mode ensures gradual migration to modules.
2038 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2039 fHeaderParsingOnDemand = !hasCxxModule;
2040
2041 // Treat Aclic Libs in a special way. Do not delay the parsing.
2042 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2043 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2044 if (hasHeaderParsingOnDemand && isACLiC) {
2045 if (gDebug>1)
2046 Info("TCling::RegisterModule",
2047 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2048 hasHeaderParsingOnDemand = false;
2049 }
2050
2051
2052 // Make sure we relookup symbols that were search for before we loaded
2053 // their autoparse information. We could be more subtil and remove only
2054 // the failed one or only the one in this module, but for now this is
2055 // better than nothing.
2056 fLookedUpClasses.clear();
2057
2058 // Make sure we do not set off AutoLoading or autoparsing during the
2059 // module registration!
2060 SuspendAutoLoadingRAII autoLoadOff(this);
2061
2062 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2063 TCling::AddIncludePath(*inclPath);
2064 }
2065 cling::Transaction* T = nullptr;
2066 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2067 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2068 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2069 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2070 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2071 assert(cling::Interpreter::kSuccess == compRes &&
2072 "A fwd declaration could not be compiled");
2073 if (compRes!=cling::Interpreter::kSuccess){
2074 Warning("TCling::RegisterModule",
2075 "Problems in declaring string '%s' were encountered.",
2076 fwdDecl.c_str()) ;
2077 continue;
2078 }
2079
2080 // Drill through namespaces recursively until the template is found
2081 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2082 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2083 }
2084
2085 }
2086
2087 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2088 // This is used to give Sema the same view on ACLiC'ed files (which
2089 // are then #included through the dictionary) as rootcling had.
2090 TString code = gNonInterpreterClassDef;
2091 if (payloadCode)
2092 code += payloadCode;
2093
2094 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2095 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2096
2097 if (dyLibName.empty()) {
2098 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2099 return;
2100 }
2101
2102 // The triggerFunc may not be in a shared object but in an executable.
2103 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2104
2105 bool wasDlopened = false;
2106
2107 // If this call happens after dlopen has finished (i.e. late registration)
2108 // there is no need to dlopen the library recursively. See ROOT-8437 where
2109 // the dyLibName would correspond to the binary.
2110 if (!lateRegistration) {
2111
2112 if (isSharedLib) {
2113 // We need to open the dictionary shared library, to resolve symbols
2114 // requested by the JIT from it: as the library is currently being dlopen'ed,
2115 // its symbols are not yet reachable from the process.
2116 // Recursive dlopen seems to work just fine.
2117 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2118 if (dyLibHandle) {
2119 fRegisterModuleDyLibs.push_back(dyLibHandle);
2120 wasDlopened = true;
2121 } else {
2122 PrintDlError(dyLibName.c_str(), modulename);
2123 }
2124 }
2125 } // if (!lateRegistration)
2126
2127 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2128 // We now parse the forward declarations. All the classes are then modified
2129 // in order for them to have an external lexical storage.
2130 std::string fwdDeclsCodeLessEnums;
2131 {
2132 // Search for enum forward decls and only declare them if no
2133 // declaration exists yet.
2134 std::string fwdDeclsLine;
2135 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2136 std::vector<std::string> scopes;
2137 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2138 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2139 // We check if the line contains a fwd declaration of an enum
2140 if (enumPos != std::string::npos) {
2141 // We clear the scopes which we may have carried from a previous iteration
2142 scopes.clear();
2143 // We check if the enum is not in a scope. If yes, save its name
2144 // and the names of the enclosing scopes.
2145 if (enumPos != 0) {
2146 // it's enclosed in namespaces. We need to understand what they are
2147 auto nsPos = fwdDeclsLine.find("namespace");
2148 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2149 while (nsPos < enumPos && nsPos != std::string::npos) {
2150 // we have a namespace, let's put it in the collection of scopes
2151 const auto nsNameStart = nsPos + 10;
2152 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2153 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2154 scopes.push_back(nsName);
2155 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2156 }
2157 }
2158 clang::DeclContext* DC = nullptr;
2159 for (auto &&aScope: scopes) {
2160 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2161 if (!DC) {
2162 // No decl context means we have to fwd declare the enum.
2163 break;
2164 }
2165 }
2166 if (scopes.empty() || DC) {
2167 // We know the scope; let's look for the enum. For that, look
2168 // for the *last* closing parentheses of an attribute because
2169 // there can be multiple.
2170 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2171 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2172 posEnumName += 5; // skip "\"))) "
2173 while (isspace(fwdDeclsLine[posEnumName]))
2174 ++posEnumName;
2175 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2176 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2177 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2178 --posEnumNameEnd;
2179 // posEnumNameEnd now points to the last character of the name.
2180
2181 std::string enumName = fwdDeclsLine.substr(posEnumName,
2182 posEnumNameEnd - posEnumName + 1);
2183
2184 if (clang::NamedDecl* enumDecl
2185 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2186 enumName.c_str(), DC)) {
2187 // We have an existing enum decl (forward or definition);
2188 // skip this.
2189 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2190 (void)enumDecl;
2191 continue;
2192 }
2193 }
2194 }
2195
2196 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2197 }
2198 }
2199
2200 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2201 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2202 assert(cling::Interpreter::kSuccess == compRes &&
2203 "The forward declarations could not be compiled");
2204 if (compRes!=cling::Interpreter::kSuccess){
2205 Warning("TCling::RegisterModule",
2206 "Problems in compiling forward declarations for module %s: '%s'",
2207 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2208 }
2209 else if (T){
2210 // Loop over all decls in the transaction and go through them all
2211 // to mark them properly.
2212 // In order to do that, we first iterate over all the DelayedCallInfos
2213 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2214 // contained in the DelayedCallInfos. For each decl, we traverse.
2215 ExtLexicalStorageAdder elsa;
2216 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2217 cling::Transaction::DelayCallInfo& dci = *dciIt;
2218 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2219 clang::Decl* declPtr = *dit;
2220 elsa.TraverseDecl(declPtr);
2221 }
2222 }
2223 }
2224 }
2225
2226 // Now we register all the headers necessary for the class
2227 // Typical format of the array:
2228 // {"A", "classes.h", "@",
2229 // "vector<A>", "vector", "@",
2230 // "myClass", payloadCode, "@",
2231 // nullptr};
2232
2233 std::string temp;
2234 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2235 temp=*classesHeader;
2236
2237 size_t theTemplateHash = 0;
2238 bool addTemplate = false;
2239 size_t posTemplate = temp.find('<');
2240 if (posTemplate != std::string::npos) {
2241 // Add an entry for the template itself.
2242 std::string templateName = temp.substr(0, posTemplate);
2243 theTemplateHash = fStringHashFunction(templateName);
2244 addTemplate = true;
2245 }
2246 size_t theHash = fStringHashFunction(temp);
2247 classesHeader++;
2248 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2249 // This is done in order to distinguish headers from files and from the payloadCode
2250 if (payloadCode == *classesHeader_inner ){
2251 fPayloads.insert(theHash);
2252 if (addTemplate) fPayloads.insert(theTemplateHash);
2253 }
2254 if (gDebug > 2)
2255 Info("TCling::RegisterModule",
2256 "Adding a header for %s", temp.c_str());
2257 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2258 if (addTemplate) {
2259 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2260 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2261 }
2262 addTemplate = false;
2263 }
2264 }
2265 }
2266 }
2267
2268 clang::Sema &TheSema = fInterpreter->getSema();
2269
2270 bool ModuleWasSuccessfullyLoaded = false;
2271 if (hasCxxModule) {
2272 std::string ModuleName = modulename;
2273 if (llvm::StringRef(modulename).startswith("lib"))
2274 ModuleName = llvm::StringRef(modulename).substr(3).str();
2275
2276 // In case we are directly loading the library via gSystem->Load() without
2277 // specifying the relevant include paths we should try loading the
2278 // modulemap next to the library location.
2279 clang::Preprocessor &PP = TheSema.getPreprocessor();
2280 std::string ModuleMapName;
2281 if (isACLiC)
2282 ModuleMapName = ModuleName + ".modulemap";
2283 else
2284 ModuleMapName = "module.modulemap";
2285 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2286 ModuleMapName);
2287
2288 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2289 // modules such as GenVector32 because it needs to fall back to GenVector.
2290 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2291 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2292 if (!ModuleWasSuccessfullyLoaded) {
2293 // Only report if we found the module in the modulemap.
2294 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2295 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2296 if (moduleMap.findModule(ModuleName))
2297 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2298 }
2299 }
2300
2301 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2302 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2303 // The path dyLibName might not be absolute. This can happen if dyLibName
2304 // is linked to an executable in the same folder.
2305 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2306 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2307 llvm::sys::path::append(pcmFileNameFullPath,
2309 LoadPCM(pcmFileNameFullPath.str().str());
2310 }
2311
2312 { // scope within which diagnostics are de-activated
2313 // For now we disable diagnostics because we saw them already at
2314 // dictionary generation time. That won't be an issue with the PCMs.
2315
2316 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2317
2318#if defined(R__MUST_REVISIT)
2319#if R__MUST_REVISIT(6,2)
2320 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2321#endif
2322#endif
2323
2324 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2325 SuspendAutoParsing autoParseRaii(this);
2326
2327 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2328 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2329 if (isACLiC) {
2330 // Register an unload point.
2331 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2332 }
2333
2334 assert(cling::Interpreter::kSuccess == compRes &&
2335 "Payload code of a dictionary could not be parsed correctly.");
2336 if (compRes!=cling::Interpreter::kSuccess) {
2337 Warning("TCling::RegisterModule",
2338 "Problems declaring payload for module %s.", modulename) ;
2339 }
2340 }
2341 }
2342
2343 // Now that all the header have been registered/compiled, let's
2344 // make sure to 'reset' the TClass that have a class init in this module
2345 // but already had their type information available (using information/header
2346 // loaded from other modules or from class rules or from opening a TFile
2347 // or from loading header in a way that did not provoke the loading of
2348 // the library we just loaded).
2350
2351 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2352 // __ROOTCLING__ might be pulled in through PCH
2353 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2354 "#undef __ROOTCLING__\n"
2355 + gInterpreterClassDef +
2356 "#endif");
2357 }
2358
2359 if (wasDlopened) {
2360 assert(isSharedLib);
2361 void* dyLibHandle = fRegisterModuleDyLibs.back();
2362 fRegisterModuleDyLibs.pop_back();
2363 dlclose(dyLibHandle);
2364 }
2365}
2366
2368 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2369 ASTContext &C = CI.getASTContext();
2370
2371 // Do not do anything if we have no global module index.
2372 // FIXME: This is mostly to real with false positives in the TTabCom
2373 // interface for non-modules.
2374 if (!fCxxModulesEnabled)
2375 return;
2376
2377 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2378 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2379 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2380 std::string I = Ident.str();
2381 if (!Idents.Contains(I.data()))
2382 Idents.Add(new TObjString(I.c_str()));
2383 }
2384 }
2385}
2386
2387
2388////////////////////////////////////////////////////////////////////////////////
2389/// Register classes that already existed prior to their dictionary loading
2390/// and that already had a ClassInfo (and thus would not be refresh via
2391/// UpdateClassInfo.
2392
2394{
2395 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2396}
2397
2398////////////////////////////////////////////////////////////////////////////////
2399/// If the dictionary is loaded, we can remove the class from the list
2400/// (otherwise the class might be loaded twice).
2401
2403{
2404 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2405 iterator stop = fClassesToUpdate.end();
2406 for(iterator i = fClassesToUpdate.begin();
2407 i != stop;
2408 ++i)
2409 {
2410 if ( i->first == oldcl ) {
2411 fClassesToUpdate.erase(i);
2412 return;
2413 }
2414 }
2415}
2416
2417
2418////////////////////////////////////////////////////////////////////////////////
2419/// Let cling process a command line.
2420///
2421/// If the command is executed and the error is 0, then the return value
2422/// is the int value corresponding to the result of the executed command
2423/// (float and double return values will be truncated).
2424///
2425
2426// Method for handling the interpreter exceptions.
2427// the MetaProcessor is passing in as argument to teh function, because
2428// cling::Interpreter::CompilationResult is a nested class and it cannot be
2429// forward declared, thus this method cannot be a static member function
2430// of TCling.
2431
2432static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2433 const char* input_line,
2434 cling::Interpreter::CompilationResult& compRes,
2435 cling::Value* result)
2436{
2437 try {
2438 return metaProcessor->process(input_line, compRes, result);
2439 }
2440 catch (cling::InterpreterException& ex)
2441 {
2442 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2443 ex.diagnose();
2444 compRes = cling::Interpreter::kFailure;
2445 }
2446 return 0;
2447}
2448
2449////////////////////////////////////////////////////////////////////////////////
2450
2451bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2452{
2453 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2454 ie->diagnose();
2455 return true;
2456 }
2457 return false;
2458}
2459
2460////////////////////////////////////////////////////////////////////////////////
2461
2463{
2464 // Copy the passed line, it comes from a static buffer in TApplication
2465 // which can be reentered through the Cling evaluation routines,
2466 // which would overwrite the static buffer and we would forget what we
2467 // were doing.
2468 //
2469 TString sLine(line);
2470 if (strstr(line,fantomline)) {
2471 // End-Of-Line action
2472 // See the comment (copied from above):
2473 // It is a "fantom" method to synchronize user keyboard input
2474 // and ROOT prompt line (for WIN32)
2475 // and is implemented by
2476 if (gApplication) {
2477 if (gApplication->IsCmdThread()) {
2479 gROOT->SetLineIsProcessing();
2480
2482
2483 gROOT->SetLineHasBeenProcessed();
2484 }
2485 }
2486 return 0;
2487 }
2488
2490 gGlobalMutex->Lock();
2491 if (!gInterpreterMutex)
2494 }
2496 gROOT->SetLineIsProcessing();
2497
2498 struct InterpreterFlagsRAII {
2499 cling::Interpreter* fInterpreter;
2500 bool fWasDynamicLookupEnabled;
2501
2502 InterpreterFlagsRAII(cling::Interpreter* interp):
2503 fInterpreter(interp),
2504 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2505 {
2506 fInterpreter->enableDynamicLookup(true);
2507 }
2508 ~InterpreterFlagsRAII() {
2509 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2510 gROOT->SetLineHasBeenProcessed();
2511 }
2512 } interpreterFlagsRAII(GetInterpreterImpl());
2513
2514 // A non-zero returned value means the given line was
2515 // not a complete statement.
2516 int indent = 0;
2517 // This will hold the resulting value of the evaluation the given line.
2518 cling::Value result;
2519 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2520 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2521 !strncmp(sLine.Data(), ".X", 2)) {
2522 // If there was a trailing "+", then CINT compiled the code above,
2523 // and we will need to strip the "+" before passing the line to cling.
2524 TString mod_line(sLine);
2525 TString aclicMode;
2526 TString arguments;
2527 TString io;
2528 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2529 aclicMode, arguments, io);
2530 if (aclicMode.Length()) {
2531 // Remove the leading '+'
2532 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2533 aclicMode[0]='k'; // We always want to keep the .so around.
2534 if (aclicMode[1]=='+') {
2535 // We have a 2nd +
2536 aclicMode[1]='f'; // We want to force the recompilation.
2537 }
2538 if (!gSystem->CompileMacro(fname,aclicMode)) {
2539 // ACLiC failed.
2540 compRes = cling::Interpreter::kFailure;
2541 } else {
2542 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2543 // if execution was requested.
2544
2545 if (arguments.Length()==0) {
2546 arguments = "()";
2547 }
2548 // We need to remove the extension.
2549 Ssiz_t ext = fname.Last('.');
2550 if (ext != kNPOS) {
2551 fname.Remove(ext);
2552 }
2553 const char *function = gSystem->BaseName(fname);
2554 mod_line = function + arguments + io;
2556 }
2557 }
2558 } else {
2559 // not ACLiC
2560 size_t unnamedMacroOpenCurly;
2561 {
2562 std::string code;
2563 std::string codeline;
2564 // Windows requires std::ifstream::binary to properly handle
2565 // CRLF and LF line endings
2566 std::ifstream in(fname, std::ifstream::binary);
2567 while (in) {
2568 std::getline(in, codeline);
2569 code += codeline + "\n";
2570 }
2571 unnamedMacroOpenCurly
2572 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2573 }
2574
2575 fCurExecutingMacros.push_back(fname);
2576 if (unnamedMacroOpenCurly != std::string::npos) {
2577 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2578 unnamedMacroOpenCurly);
2579 } else {
2580 // No DynLookup for .x, .L of named macros.
2581 fInterpreter->enableDynamicLookup(false);
2583 }
2584 fCurExecutingMacros.pop_back();
2585 }
2586 } // .L / .X / .x
2587 else {
2588 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2589 // explicitly ignore .autodict without having to support it
2590 // in cling.
2591
2592 // Turn off autoparsing if this is an include directive
2593 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2594 if (isInclusionDirective) {
2595 SuspendAutoParsing autoParseRaii(this);
2597 } else {
2599 }
2600 }
2601 }
2602 if (result.isValid())
2604 if (indent) {
2605 if (error)
2606 *error = kProcessing;
2607 return 0;
2608 }
2609 if (error) {
2610 switch (compRes) {
2611 case cling::Interpreter::kSuccess: *error = kNoError; break;
2612 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2613 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2614 }
2615 }
2616 if (compRes == cling::Interpreter::kSuccess
2617 && result.isValid()
2618 && !result.isVoid())
2619 {
2620 return result.castAs<Longptr_t>();
2621 }
2622 return 0;
2623}
2624
2625////////////////////////////////////////////////////////////////////////////////
2626/// No-op; see TRint instead.
2627
2629{
2630}
2631
2632////////////////////////////////////////////////////////////////////////////////
2633/// \brief Add a directory to the list of directories in which the
2634/// interpreter looks for include files.
2635/// \param[in] path The path to the directory.
2636/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2637/// \b NOT supported.
2638/// \warning Only the path to the directory should be specified, without
2639/// prepending the \c -I prefix, i.e.
2640/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2641/// \c -I prefix is used it will be ignored.
2642void TCling::AddIncludePath(const char *path)
2643{
2645 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2646 // gCling->AddIncludePath() does not! Work around that inconsistency:
2647 if (path[0] == '-' && path[1] == 'I')
2648 path += 2;
2649 TString sPath(path);
2650 gSystem->ExpandPathName(sPath);
2651#ifdef _MSC_VER
2652 if (sPath.BeginsWith("/")) {
2653 char drive[3];
2654 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2655 sPath.Prepend(drive);
2656 }
2657#endif
2658 fInterpreter->AddIncludePath(sPath.Data());
2659}
2660
2661////////////////////////////////////////////////////////////////////////////////
2662/// Visit all members over members, recursing over base classes.
2663
2664void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2665 const TClass* cl, Bool_t isTransient)
2666{
2670 }
2671
2672 if (!cl || cl->GetCollectionProxy()) {
2673 // We do not need to investigate the content of the STL
2674 // collection, they are opaque to us (and details are
2675 // uninteresting).
2676 return;
2677 }
2678
2679 static const TClassRef clRefString("std::string");
2680 if (clRefString == cl) {
2681 // We stream std::string without going through members..
2682 return;
2683 }
2684
2685 if (TClassEdit::IsStdArray(cl->GetName())) {
2686 // We treat std arrays as C arrays
2687 return;
2688 }
2689
2690 const char* cobj = (const char*) obj; // for ptr arithmetics
2691
2692 // Treat the case of std::complex in a special manner. We want to enforce
2693 // the layout of a stl implementation independent class, which is the
2694 // complex as implemented in ROOT5.
2695
2696 // A simple lambda to simplify the code
2697 auto inspInspect = [&] (ptrdiff_t offset){
2698 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2699 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2700 };
2701
2702 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2703 switch(complexType) {
2705 {
2706 break;
2707 }
2709 {
2710 inspInspect(sizeof(float));
2711 return;
2712 }
2714 {
2715 inspInspect(sizeof(double));
2716 return;
2717 }
2719 {
2720 inspInspect(sizeof(int));
2721 return;
2722 }
2724 {
2725 inspInspect(sizeof(long));
2726 return;
2727 }
2728 }
2729
2730 static clang::PrintingPolicy
2731 printPol(fInterpreter->getCI()->getLangOpts());
2732 if (printPol.Indentation) {
2733 // not yet initialized
2734 printPol.Indentation = 0;
2735 printPol.SuppressInitializers = true;
2736 }
2737
2738 const char* clname = cl->GetName();
2739 // Printf("Inspecting class %s\n", clname);
2740
2741 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2742 const clang::Decl *scopeDecl = nullptr;
2743 const clang::Type *recordType = nullptr;
2744
2745 if (cl->GetClassInfo()) {
2746 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2747 scopeDecl = clingCI->GetDecl();
2748 recordType = clingCI->GetType();
2749 } else {
2750 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2751 // Diags will complain about private classes:
2752 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2753 &recordType);
2754 }
2755 if (!scopeDecl) {
2756 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2757 return;
2758 }
2759 const clang::CXXRecordDecl* recordDecl
2760 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2761 if (!recordDecl) {
2762 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2763 return;
2764 }
2765
2766 {
2767 // Force possible deserializations first. We need to have no pending
2768 // Transaction when passing control flow to the inspector below (ROOT-7779).
2769 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2770
2771 astContext.getASTRecordLayout(recordDecl);
2772
2773 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2774 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2775 }
2776
2777 const clang::ASTRecordLayout& recLayout
2778 = astContext.getASTRecordLayout(recordDecl);
2779
2780 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2781 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2782 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2783 // cl->GetName());
2784 // }
2785 if (cl->Size() != recLayout.getSize().getQuantity()) {
2786 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2787 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2788 }
2789
2790 unsigned iNField = 0;
2791 // iterate over fields
2792 // FieldDecls are non-static, else it would be a VarDecl.
2793 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2794 eField = recordDecl->field_end(); iField != eField;
2795 ++iField, ++iNField) {
2796
2797
2798 clang::QualType memberQT = iField->getType();
2799 if (recordType) {
2800 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2801 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2802 }
2803 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2804 if (memberQT.isNull()) {
2805 std::string memberName;
2806 llvm::raw_string_ostream stream(memberName);
2807 // Don't trigger fopen of the source file to count lines:
2808 printPol.AnonymousTagLocations = false;
2809 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2810 stream.flush();
2811 Error("InspectMembers",
2812 "Cannot retrieve QualType for member %s while inspecting class %s",
2813 memberName.c_str(), clname);
2814 continue; // skip member
2815 }
2816 const clang::Type* memType = memberQT.getTypePtr();
2817 if (!memType) {
2818 std::string memberName;
2819 llvm::raw_string_ostream stream(memberName);
2820 // Don't trigger fopen of the source file to count lines:
2821 printPol.AnonymousTagLocations = false;
2822 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2823 stream.flush();
2824 Error("InspectMembers",
2825 "Cannot retrieve Type for member %s while inspecting class %s",
2826 memberName.c_str(), clname);
2827 continue; // skip member
2828 }
2829
2830 const clang::Type* memNonPtrType = memType;
2831 Bool_t ispointer = false;
2832 if (memNonPtrType->isPointerType()) {
2833 ispointer = true;
2834 clang::QualType ptrQT
2835 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2836 if (recordType) {
2837 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2838 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2839 }
2840 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2841 if (ptrQT.isNull()) {
2842 std::string memberName;
2843 llvm::raw_string_ostream stream(memberName);
2844 // Don't trigger fopen of the source file to count lines:
2845 printPol.AnonymousTagLocations = false;
2846 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2847 stream.flush();
2848 Error("InspectMembers",
2849 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2850 memberName.c_str(), clname);
2851 continue; // skip member
2852 }
2853 memNonPtrType = ptrQT.getTypePtr();
2854 }
2855
2856 // assemble array size(s): "[12][4][]"
2857 llvm::SmallString<8> arraySize;
2858 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2859 unsigned arrLevel = 0;
2860 bool haveErrorDueToArray = false;
2861 while (arrType) {
2862 ++arrLevel;
2863 arraySize += '[';
2864 const clang::ConstantArrayType* constArrType =
2865 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2866 if (constArrType) {
2867 constArrType->getSize().toStringUnsigned(arraySize);
2868 }
2869 arraySize += ']';
2870 clang::QualType subArrQT = arrType->getElementType();
2871 if (subArrQT.isNull()) {
2872 std::string memberName;
2873 llvm::raw_string_ostream stream(memberName);
2874 // Don't trigger fopen of the source file to count lines:
2875 printPol.AnonymousTagLocations = false;
2876 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2877 stream.flush();
2878 Error("InspectMembers",
2879 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2880 arrLevel, subArrQT.getAsString(printPol).c_str(),
2881 memberName.c_str(), clname);
2882 haveErrorDueToArray = true;
2883 break;
2884 }
2885 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2886 }
2887 if (haveErrorDueToArray) {
2888 continue; // skip member
2889 }
2890
2891 // construct member name
2892 std::string fieldName;
2893 if (memType->isPointerType()) {
2894 fieldName = "*";
2895 }
2896
2897 // Check if this field has a custom ioname, if not, just use the one of the decl
2898 std::string ioname(iField->getName());
2899 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2900 fieldName += ioname;
2901 fieldName += arraySize;
2902
2903 // get member offset
2904 // NOTE currently we do not support bitfield and do not support
2905 // member that are not aligned on 'bit' boundaries.
2906 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2907 ptrdiff_t fieldOffset = offset.getQuantity();
2908
2909 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2910 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2911 // R__insp.InspectMember(fName, "fName.");
2912 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2913
2914 // If the class has a custom streamer and the type of the filed is a
2915 // private enum, struct or class, skip it.
2916 if (!insp.IsTreatingNonAccessibleTypes()){
2917 auto iFiledQtype = iField->getType();
2918 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2919 auto declAccess = tagDecl->getAccess();
2920 if (declAccess == AS_private || declAccess == AS_protected) {
2921 continue;
2922 }
2923 }
2924 }
2925
2926 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2927
2928 if (!ispointer) {
2929 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2930 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2931 // nested objects get an extra call to InspectMember
2932 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2933 std::string sFieldRecName;
2934 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2936 clang::QualType(memNonPtrType,0),
2937 *fInterpreter,
2939 }
2940
2941 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2942 // if we can not find the member (which should not really happen),
2943 // let's consider it transient.
2944 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2945
2946 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2947 (fieldName + '.').c_str(), transient);
2948
2949 }
2950 }
2951 } // loop over fields
2952
2953 // inspect bases
2954 // TNamed::ShowMembers(R__insp);
2955 unsigned iNBase = 0;
2956 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2957 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2958 iBase != eBase; ++iBase, ++iNBase) {
2959 clang::QualType baseQT = iBase->getType();
2960 if (baseQT.isNull()) {
2961 Error("InspectMembers",
2962 "Cannot find QualType for base number %d while inspecting class %s",
2963 iNBase, clname);
2964 continue;
2965 }
2966 const clang::CXXRecordDecl* baseDecl
2967 = baseQT->getAsCXXRecordDecl();
2968 if (!baseDecl) {
2969 Error("InspectMembers",
2970 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2971 iNBase, clname);
2972 continue;
2973 }
2974 TClass* baseCl=nullptr;
2975 std::string sBaseName;
2976 // Try with the DeclId
2977 std::vector<TClass*> foundClasses;
2978 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2979 if (foundClasses.size()==1){
2980 baseCl=foundClasses[0];
2981 } else {
2982 // Try with the normalised Name, as a fallback
2983 if (!baseCl){
2985 baseQT,
2986 *fInterpreter,
2988 baseCl = TClass::GetClass(sBaseName.c_str());
2989 }
2990 }
2991
2992 if (!baseCl){
2993 std::string qualNameForDiag;
2994 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2995 Error("InspectMembers",
2996 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2997 continue;
2998 }
2999
3000 int64_t baseOffset;
3001 if (iBase->isVirtual()) {
3003 if (!isTransient) {
3004 Error("InspectMembers",
3005 "Base %s of class %s is virtual but no object provided",
3006 sBaseName.c_str(), clname);
3007 }
3009 } else {
3010 // We have an object to determine the vbase offset.
3012 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3013 if (ci && baseCi) {
3014 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3015 true /*isDerivedObj*/);
3016 if (baseOffset == -1) {
3017 Error("InspectMembers",
3018 "Error calculating offset of virtual base %s of class %s",
3019 sBaseName.c_str(), clname);
3020 }
3021 } else {
3022 Error("InspectMembers",
3023 "Cannot calculate offset of virtual base %s of class %s",
3024 sBaseName.c_str(), clname);
3025 continue;
3026 }
3027 }
3028 } else {
3029 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3030 }
3031 // TOFIX: baseCl can be null here!
3032 if (baseCl->IsLoaded()) {
3033 // For loaded class, CallShowMember will (especially for TObject)
3034 // call the virtual ShowMember rather than the class specific version
3035 // resulting in an infinite recursion.
3036 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3037 } else {
3038 baseCl->CallShowMembers(cobj + baseOffset,
3039 insp, isTransient);
3040 }
3041 } // loop over bases
3042}
3043
3044////////////////////////////////////////////////////////////////////////////////
3045/// Reset the interpreter internal state in case a previous action was not correctly
3046/// terminated.
3047
3049{
3050 // No-op there is not equivalent state (to be cleared) in Cling.
3051}
3052
3053////////////////////////////////////////////////////////////////////////////////
3054/// Delete existing temporary values.
3055
3057{
3058 // No-op for cling due to cling::Value.
3059}
3060
3061////////////////////////////////////////////////////////////////////////////////
3062/// Declare code to the interpreter, without any of the interpreter actions
3063/// that could trigger a re-interpretation of the code. I.e. make cling
3064/// behave like a compiler: no dynamic lookup, no input wrapping for
3065/// subsequent execution, no automatic provision of declarations but just a
3066/// plain `#include`.
3067/// Returns true on success, false on failure.
3068
3069bool TCling::Declare(const char* code)
3070{
3072
3073 SuspendAutoLoadingRAII autoLoadOff(this);
3074 SuspendAutoParsing autoParseRaii(this);
3075
3076 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3077 fInterpreter->enableDynamicLookup(false);
3078 bool oldRawInput = fInterpreter->isRawInputEnabled();
3079 fInterpreter->enableRawInput(true);
3080
3081 Bool_t ret = LoadText(code);
3082
3083 fInterpreter->enableRawInput(oldRawInput);
3084 fInterpreter->enableDynamicLookup(oldDynLookup);
3085 return ret;
3086}
3087
3088////////////////////////////////////////////////////////////////////////////////
3089/// It calls a "fantom" method to synchronize user keyboard input
3090/// and ROOT prompt line.
3091
3093{
3095}
3096
3097// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3098// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3099// was already taking a lock.
3100static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3101{
3102 // Check shared library.
3103 TString tLibName(libname);
3104 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3105 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3106 return false;
3107}
3108
3109Bool_t TCling::IsLibraryLoaded(const char* libname) const
3110{
3112 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3113}
3114
3115////////////////////////////////////////////////////////////////////////////////
3116/// Return true if ROOT has cxxmodules pcm for a given library name.
3117// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3118Bool_t TCling::HasPCMForLibrary(const char *libname) const
3119{
3120 llvm::StringRef ModuleName(libname);
3121 ModuleName = llvm::sys::path::stem(ModuleName);
3122 ModuleName.consume_front("lib");
3123
3124 // FIXME: In case when the modulemap is not yet loaded we will return the
3125 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3126 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3127 // which may happen after calling this interface. Maybe we should also check
3128 // if there is a Event.pcm file and a module.modulemap, load it and return
3129 // true.
3130 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3131 clang::Module *M = moduleMap.findModule(ModuleName);
3132 return M && !M->IsUnimportable && M->getASTFile();
3133}
3134
3135////////////////////////////////////////////////////////////////////////////////
3136/// Return true if the file has already been loaded by cint.
3137/// We will try in this order:
3138/// actual filename
3139/// filename as a path relative to
3140/// the include path
3141/// the shared library path
3142
3144{
3146
3147 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3148 // cling::DynamicLibraryManager.
3149
3150 std::string file_name = filename;
3151 size_t at = std::string::npos;
3152 while ((at = file_name.find("/./")) != std::string::npos)
3153 file_name.replace(at, 3, "/");
3154
3155 std::string filesStr = "";
3156 llvm::raw_string_ostream filesOS(filesStr);
3157 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3158 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3159 filesOS.flush();
3160
3161 llvm::SmallVector<llvm::StringRef, 100> files;
3162 llvm::StringRef(filesStr).split(files, "\n");
3163
3164 std::set<std::string> fileMap;
3165 llvm::StringRef file_name_ref(file_name);
3166 // Fill fileMap; return early on exact match.
3167 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3168 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3169 if ((*iF) == file_name_ref) return kTRUE; // exact match
3170 fileMap.insert(iF->str());
3171 }
3172
3173 if (fileMap.empty()) return kFALSE;
3174
3175 // Check MacroPath.
3176 TString sFilename(file_name.c_str());
3178 && fileMap.count(sFilename.Data())) {
3179 return kTRUE;
3180 }
3181
3182 // Check IncludePath.
3183 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3184 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3185 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3186 while (incPath.Index(" :") != -1) {
3187 incPath.ReplaceAll(" :", ":");
3188 }
3189 incPath.Prepend(".:");
3190 sFilename = file_name.c_str();
3191 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3192 && fileMap.count(sFilename.Data())) {
3193 return kTRUE;
3194 }
3195
3196 // Check shared library.
3197 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3198 return kTRUE;
3199
3200 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3201 clang::ConstSearchDirIterator *CurDir = nullptr;
3202 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3203 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3204 auto FE = HS.LookupFile(file_name.c_str(),
3205 clang::SourceLocation(),
3206 /*isAngled*/ false,
3207 /*FromDir*/ nullptr, CurDir,
3208 clang::ArrayRef<std::pair<const clang::FileEntry *,
3209 const clang::DirectoryEntry *>>(),
3210 /*SearchPath*/ nullptr,
3211 /*RelativePath*/ nullptr,
3212 /*RequestingModule*/ nullptr,
3213 /*SuggestedModule*/ nullptr,
3214 /*IsMapped*/ nullptr,
3215 /*IsFrameworkFound*/ nullptr,
3216 /*SkipCache*/ false,
3217 /*BuildSystemModule*/ false,
3218 /*OpenFile*/ false,
3219 /*CacheFail*/ false);
3220 if (FE) {
3221 // check in the source manager if the file is actually loaded
3222 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3223 // this works only with header (and source) files...
3224 clang::FileID FID = SM.translateFile(*FE);
3225 if (!FID.isInvalid() && FID.getHashValue() == 0)
3226 return kFALSE;
3227 else {
3228 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3229 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3230 return kFALSE;
3231 if (!FID.isInvalid())
3232 return kTRUE;
3233 }
3234 // ...then check shared library again, but with full path now
3235 sFilename = FE->getName().str();
3236 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3237 && fileMap.count(sFilename.Data())) {
3238 return kTRUE;
3239 }
3240 }
3241 return kFALSE;
3242}
3243
3244
3245#if defined(R__MACOSX)
3246
3247////////////////////////////////////////////////////////////////////////////////
3248/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3249/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3250/// to `-lFOO` such that it can be passed to the linker.
3251/// This is a unique feature of macOS 11.
3252
3253static bool R__UpdateLibFileForLinking(TString &lib)
3254{
3255 const char *mapfile = nullptr;
3256#if __x86_64__
3257 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3258#elif __arm64__
3259 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3260#else
3261 #error unsupported architecture
3262#endif
3263 if (std::ifstream cacheMap{mapfile}) {
3264 std::string line;
3265 while (getline(cacheMap, line)) {
3266 if (line.find(lib) != std::string::npos) {
3267 lib.ReplaceAll("/usr/lib/lib","-l");
3268 lib.ReplaceAll(".dylib","");
3269 return true;
3270 }
3271 }
3272 return false;
3273 }
3274 return false;
3275}
3276#endif // R__MACOSX
3277
3278#if defined (R__LINUX) || defined (R__FBSD)
3279
3280////////////////////////////////////////////////////////////////////////////////
3281/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3282/// Collects opened libraries.
3283
3284static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3285{
3286 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3287 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3288
3289 auto newLibs = static_cast<std::vector<std::string>*>(data);
3290 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3291 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3292 if (info->dlpi_name && info->dlpi_name[0]
3293#if defined(R__FBSD)
3294 //skip the executable (with null addr)
3295 && info->dlpi_addr
3296 //has no path
3297 && strncmp(info->dlpi_name, "[vdso]", 6)
3298 //the linker does not like to be mmapped
3299 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3300 //with error message "mmap of entire address space failed: Cannot allocate memory"
3301 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3302#endif
3303 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3304 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3305 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3306 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3307 newLibs->emplace_back(info->dlpi_name);
3308 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3309 }
3310 // No matter what the doc says, return != 0 means "stop the iteration".
3311 return 0;
3312}
3313
3314#endif // R__LINUX || R__FBSD
3315
3316
3317////////////////////////////////////////////////////////////////////////////////
3318
3320{
3321#if defined(R__WIN32) || defined(__CYGWIN__)
3322 HMODULE hModules[1024];
3323 void *hProcess;
3324 unsigned long cbModules;
3325 unsigned int i;
3326 hProcess = (void *)::GetCurrentProcess();
3327 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3328 // start at 1 to skip the executable itself
3329 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3330 static const int bufsize = 260;
3331 wchar_t winname[bufsize];
3332 char posixname[bufsize];
3333 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3334#if defined(__CYGWIN__)
3335 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3336#else
3337 std::wstring wpath = winname;
3338 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3339 string path(wpath.begin(), wpath.end());
3340 strncpy(posixname, path.c_str(), bufsize);
3341#endif
3342 if (!fSharedLibs.Contains(posixname)) {
3343 RegisterLoadedSharedLibrary(posixname);
3344 }
3345 }
3346#elif defined(R__MACOSX)
3347 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3348 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3349
3350 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3351 // Skip non-dylibs
3352 if (mh->filetype == MH_DYLIB) {
3353 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3354 RegisterLoadedSharedLibrary(imageName);
3355 }
3356 }
3357
3358 ++imageIndex;
3359 }
3360 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3361#elif defined(R__LINUX) || defined(R__FBSD)
3362 // fPrevLoadedDynLibInfo is unused on Linux.
3363 (void) fPrevLoadedDynLibInfo;
3364
3365 std::vector<std::string> newLibs;
3366 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3367 for (auto &&lib: newLibs)
3368 RegisterLoadedSharedLibrary(lib.c_str());
3369#else
3370 Error("TCling::UpdateListOfLoadedSharedLibraries",
3371 "Platform not supported!");
3372#endif
3373}
3374
3375namespace {
3376template <int N>
3377static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3378 return !strncmp(haystack, needle, N - 1);
3379}
3380}
3381
3382////////////////////////////////////////////////////////////////////////////////
3383/// Register a new shared library name with the interpreter; add it to
3384/// fSharedLibs.
3385
3387{
3388 // Ignore NULL filenames, aka "the process".
3389 if (!filename) return;
3390
3391 // Tell the interpreter that this library is available; all libraries can be
3392 // used to resolve symbols.
3393 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3394 if (!DLM->isLibraryLoaded(filename)) {
3395 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3396 }
3397
3398#if defined(R__MACOSX)
3399 // Check that this is not a system library that does not exist on disk.
3400 auto lenFilename = strlen(filename);
3401 auto isInMacOSSystemDir = [](const char *fn) {
3402 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3403 };
3404 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3405
3406 // These we should not link with (e.g. because they forward to .tbd):
3407 || StartsWithStrLit(filename, "/usr/lib/system/")
3408 || StartsWithStrLit(filename, "/usr/lib/libc++")
3409 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3410 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3411 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3412 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3413 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3414 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3415 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3416 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3417 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3418 || StartsWithStrLit(filename, "/usr/lib/libauto")
3419 || StartsWithStrLit(filename, "/usr/lib/libcups")
3420 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3421 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3422 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3423 || StartsWithStrLit(filename, "/usr/lib/libpam")
3424 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3425 || StartsWithStrLit(filename, "/usr/lib/libextension")
3426 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3427 || StartsWithStrLit(filename, "/usr/lib/liboah")
3428 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3429 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3430 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3431 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3432
3433 // The system lib is likely in macOS's blob.
3434 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3435
3436 // "Link against the umbrella framework 'System.framework' instead"
3437 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3438 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3439 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3440
3441 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3442 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3443 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3444 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3445 return;
3446 TString sFileName(filename);
3447 R__UpdateLibFileForLinking(sFileName);
3448 filename = sFileName.Data();
3449#elif defined(__CYGWIN__)
3450 // Check that this is not a system library
3451 static const int bufsize = 260;
3452 char posixwindir[bufsize];
3453 char *windir = getenv("WINDIR");
3454 if (windir)
3455 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3456 else
3457 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3458 if (strstr(filename, posixwindir) ||
3459 strstr(filename, "/usr/bin/cyg"))
3460 return;
3461#elif defined(R__WIN32)
3462 if (strstr(filename, "/Windows/"))
3463 return;
3464#elif defined (R__LINUX)
3465 if (strstr(filename, "/ld-linux")
3466 || strstr(filename, "linux-gnu/")
3467 || strstr(filename, "/libstdc++.")
3468 || strstr(filename, "/libgcc")
3469 || strstr(filename, "/libc.")
3470 || strstr(filename, "/libdl.")
3471 || strstr(filename, "/libm."))
3472 return;
3473#endif
3474 // Update string of available libraries.
3475 if (!fSharedLibs.IsNull()) {
3476 fSharedLibs.Append(" ");
3477 }
3479}
3480
3481////////////////////////////////////////////////////////////////////////////////
3482/// Load a library file in cling's memory.
3483/// if 'system' is true, the library is never unloaded.
3484/// Return 0 on success, -1 on failure.
3485
3486Int_t TCling::Load(const char* filename, Bool_t system)
3487{
3488 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3489
3490 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3492 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3493 std::string canonLib = DLM->lookupLibrary(filename);
3494 cling::DynamicLibraryManager::LoadLibResult res
3495 = cling::DynamicLibraryManager::kLoadLibNotFound;
3496 if (!canonLib.empty()) {
3497 if (system)
3498 res = DLM->loadLibrary(filename, system, true);
3499 else {
3500 // For the non system libs, we'd like to be able to unload them.
3501 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3502 cling::Interpreter::CompilationResult compRes;
3503 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3504 if (compRes == cling::Interpreter::kSuccess)
3505 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3506 }
3507 }
3508
3509 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3511 }
3512 switch (res) {
3513 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3514 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3515 default: break;
3516 };
3517 return -1;
3518}
3519
3520////////////////////////////////////////////////////////////////////////////////
3521/// Load a macro file in cling's memory.
3522
3523void TCling::LoadMacro(const char* filename, EErrorCode* error)
3524{
3525 ProcessLine(Form(".L %s", filename), error);
3526}
3527
3528////////////////////////////////////////////////////////////////////////////////
3529/// Let cling process a command line asynch.
3530
3532{
3533 return ProcessLine(line, error);
3534}
3535
3536////////////////////////////////////////////////////////////////////////////////
3537/// Let cling process a command line synchronously, i.e we are waiting
3538/// it will be finished.
3539
3541{
3543 if (gApplication) {
3544 if (gApplication->IsCmdThread()) {
3545 return ProcessLine(line, error);
3546 }
3547 return 0;
3548 }
3549 return ProcessLine(line, error);
3550}
3551
3552////////////////////////////////////////////////////////////////////////////////
3553/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3554/// however not declarations, like "Int_t x;").
3555
3557{
3558#ifdef R__WIN32
3559 // Test on ApplicationImp not being 0 is needed because only at end of
3560 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3561 // we can not use it.
3563 while (gROOT->IsLineProcessing() && !gApplication) {
3564 Warning("Calc", "waiting for cling thread to free");
3565 gSystem->Sleep(500);
3566 }
3567 gROOT->SetLineIsProcessing();
3568 }
3569#endif // R__WIN32
3571 if (error) {
3572 *error = TInterpreter::kNoError;
3573 }
3574 cling::Value valRef;
3575 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3576 try {
3577 cr = fInterpreter->evaluate(line, valRef);
3578 }
3579 catch (cling::InterpreterException& ex)
3580 {
3581 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3582 ex.diagnose();
3583 cr = cling::Interpreter::kFailure;
3584 }
3585
3586 if (cr != cling::Interpreter::kSuccess) {
3587 // Failure in compilation.
3588 if (error) {
3589 // Note: Yes these codes are weird.
3591 }
3592 return 0L;
3593 }
3594 if (!valRef.isValid()) {
3595 // Failure at runtime.
3596 if (error) {
3597 // Note: Yes these codes are weird.
3598 *error = TInterpreter::kDangerous;
3599 }
3600 return 0L;
3601 }
3602
3603 if (valRef.isVoid()) {
3604 return 0;
3605 }
3606
3607 RegisterTemporary(valRef);
3608#ifdef R__WIN32
3610 gROOT->SetLineHasBeenProcessed();
3611 }
3612#endif // R__WIN32
3613 return valRef.castAs<Longptr_t>();
3614}
3615
3616////////////////////////////////////////////////////////////////////////////////
3617/// Set a getline function to call when input is needed.
3618
3619void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3620 void (*histaddFunc)(const char* line))
3621{
3622 // If cling offers a replacement for G__pause(), it would need to
3623 // also offer a way to customize at least the history recording.
3624
3625#if defined(R__MUST_REVISIT)
3626#if R__MUST_REVISIT(6,2)
3627 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3628#endif
3629#endif
3630}
3631
3632////////////////////////////////////////////////////////////////////////////////
3633/// Helper function to increase the internal Cling count of transactions
3634/// that change the AST.
3635
3636Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3637{
3639
3640 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3641 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3642 || T.macros_begin() != T.macros_end()
3643 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3645 return true;
3646 }
3647 return false;
3648}
3649
3650////////////////////////////////////////////////////////////////////////////////
3651/// Delete object from cling symbol table so it can not be used anymore.
3652/// cling objects are always on the heap.
3653
3655{
3656 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3657 // put in place the Read/Write part here. Keeping the write lock
3658 // here is 'catasptrophic' for scaling as it means that ALL calls
3659 // to RecursiveRemove will take the write lock and performance
3660 // of many threads trying to access the write lock at the same
3661 // time is relatively bad.
3663 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3664 // (but isn't at the moment).
3665 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3666 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3667 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3669 DeleteGlobal(obj);
3670 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3671 }
3672 }
3673}
3674
3675////////////////////////////////////////////////////////////////////////////////
3676/// Pressing Ctrl+C should forward here. In the case where we have had
3677/// continuation requested we must reset it.
3678
3680{
3681 fMetaProcessor->cancelContinuation();
3682 // Reset the Cling state to the state saved by the last call to
3683 // TCling::SaveContext().
3684#if defined(R__MUST_REVISIT)
3685#if R__MUST_REVISIT(6,2)
3687 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3688#endif
3689#endif
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Reset the Cling state to its initial state.
3694
3696{
3697#if defined(R__MUST_REVISIT)
3698#if R__MUST_REVISIT(6,2)
3700 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3701#endif
3702#endif
3703}
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// Reset in Cling the list of global variables to the state saved by the last
3707/// call to TCling::SaveGlobalsContext().
3708///
3709/// Note: Right now, all we do is run the global destructors.
3710
3712{
3714 // TODO:
3715 // Here we should iterate over the transactions (N-3) and revert.
3716 // N-3 because the first three internal to cling.
3717
3718 fInterpreter->runAndRemoveStaticDestructors();
3719}
3720
3721////////////////////////////////////////////////////////////////////////////////
3722/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3723/// call to TCling::SaveGlobalsContext().
3724
3726{
3727#if defined(R__MUST_REVISIT)
3728#if R__MUST_REVISIT(6,2)
3730 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3731#endif
3732#endif
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// Rewind Cling dictionary to the point where it was before executing
3737/// the current macro. This function is typically called after SEGV or
3738/// ctlr-C after doing a longjmp back to the prompt.
3739
3741{
3742#if defined(R__MUST_REVISIT)
3743#if R__MUST_REVISIT(6,2)
3745 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3746#endif
3747#endif
3748}
3749
3750////////////////////////////////////////////////////////////////////////////////
3751/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3752/// Returns 1 in case of success and 0 in case object was not in table.
3753
3755{
3756#if defined(R__MUST_REVISIT)
3757#if R__MUST_REVISIT(6,2)
3759 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3760#endif
3761#endif
3762 return 0;
3763}
3764
3765////////////////////////////////////////////////////////////////////////////////
3766/// Undeclare obj called name.
3767/// Returns 1 in case of success, 0 for failure.
3768
3770{
3771#if defined(R__MUST_REVISIT)
3772#if R__MUST_REVISIT(6,2)
3773 Warning("DeleteVariable","should do more that just reseting the value to zero");
3774#endif
3775#endif
3776
3778 llvm::StringRef srName(name);
3779 const char* unscopedName = name;
3780 llvm::StringRef::size_type posScope = srName.rfind("::");
3781 const clang::DeclContext* declCtx = nullptr;
3782 if (posScope != llvm::StringRef::npos) {
3783 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3784 const clang::Decl* scopeDecl
3785 = lh.findScope(srName.substr(0, posScope),
3786 cling::LookupHelper::WithDiagnostics);
3787 if (!scopeDecl) {
3788 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3789 name);
3790 return 0;
3791 }
3792 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3793 if (!declCtx) {
3794 Error("DeleteVariable",
3795 "Enclosing scope for variable %s is not a declaration context",
3796 name);
3797 return 0;
3798 }
3799 unscopedName += posScope + 2;
3800 }
3801 // Could trigger deserialization of decls.
3802 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3803 clang::NamedDecl* nVarDecl
3804 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3805 if (!nVarDecl) {
3806 Error("DeleteVariable", "Unknown variable %s", name);
3807 return 0;
3808 }
3809 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3810 if (!varDecl) {
3811 Error("DeleteVariable", "Entity %s is not a variable", name);
3812 return 0;
3813 }
3814
3815 clang::QualType qType = varDecl->getType();
3816 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3817 // Cannot set a reference's address to nullptr; the JIT can place it
3818 // into read-only memory (ROOT-7100).
3819 if (type->isPointerType()) {
3820 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3821 // set pointer to invalid.
3822 if (ppInt) *ppInt = nullptr;
3823 }
3824 return 1;
3825}
3826
3827////////////////////////////////////////////////////////////////////////////////
3828/// Save the current Cling state.
3829
3831{
3832#if defined(R__MUST_REVISIT)
3833#if R__MUST_REVISIT(6,2)
3835 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3836#endif
3837#endif
3838}
3839
3840////////////////////////////////////////////////////////////////////////////////
3841/// Save the current Cling state of global objects.
3842
3844{
3845#if defined(R__MUST_REVISIT)
3846#if R__MUST_REVISIT(6,2)
3848 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3849#endif
3850#endif
3851}
3852
3853////////////////////////////////////////////////////////////////////////////////
3854/// No op: see TClingCallbacks (used to update the list of globals)
3855
3857{
3858}
3859
3860////////////////////////////////////////////////////////////////////////////////
3861/// No op: see TClingCallbacks (used to update the list of global functions)
3862
3864{
3865}
3866
3867////////////////////////////////////////////////////////////////////////////////
3868/// No op: see TClingCallbacks (used to update the list of types)
3869
3871{
3872}
3873
3874////////////////////////////////////////////////////////////////////////////////
3875/// Check in what order the member of a tuple are layout.
3876enum class ETupleOrdering {
3877 kAscending,
3880};
3881
3883{
3886};
3887
3889{
3892};
3893
3895{
3896 std::tuple<int,double> value;
3899
3900 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3901 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3902
3903 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3904 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3905
3906 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3907 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3908
3909 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3911 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3913 } else {
3915 }
3916}
3917
3918static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3919{
3920 TClassEdit::TSplitType tupleContent(classname);
3921 std::string alternateName = "TEmulatedTuple";
3922 alternateName.append( classname + 5 );
3923
3924 std::string fullname = "ROOT::Internal::" + alternateName;
3925 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3926 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3927 return fullname;
3928
3929 std::string guard_name;
3930 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3931 std::ostringstream guard;
3932 guard << "ROOT_INTERNAL_TEmulated_";
3933 guard << guard_name;
3934
3935 std::ostringstream alternateTuple;
3936 alternateTuple << "#ifndef " << guard.str() << "\n";
3937 alternateTuple << "#define " << guard.str() << "\n";
3938 alternateTuple << "namespace ROOT { namespace Internal {\n";
3939 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3940 alternateTuple << "template <> struct " << alternateName << " {\n";
3941
3942 // This could also be a compile time choice ...
3943 switch(IsTupleAscending()) {
3945 unsigned int nMember = 0;
3946 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3947 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3948 while (iter != theEnd) {
3949 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3950 ++iter;
3951 ++nMember;
3952 }
3953 break;
3954 }
3956 unsigned int nMember = tupleContent.fElements.size() - 3;
3957 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3958 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3959 while (iter != theEnd) {
3960 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3961 ++iter;
3962 --nMember;
3963 }
3964 break;
3965 }
3967 Fatal("TCling::SetClassInfo::AlternateTuple",
3968 "Layout of std::tuple on this platform is unexpected.");
3969 break;
3970 }
3971 }
3972
3973 alternateTuple << "};\n";
3974 alternateTuple << "}}\n";
3975 alternateTuple << "#endif\n";
3976 if (!gCling->Declare(alternateTuple.str().c_str())) {
3977 Error("Load","Could not declare %s",alternateName.c_str());
3978 return "";
3979 }
3980 alternateName = "ROOT::Internal::" + alternateName;
3981 return alternateName;
3982}
3983
3984////////////////////////////////////////////////////////////////////////////////
3985/// Set pointer to the TClingClassInfo in TClass.
3986/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3987/// already have one.
3988
3990{
3991 // We are shutting down, there is no point in reloading, it only triggers
3992 // redundant deserializations.
3993 if (fIsShuttingDown) {
3994 // Remove the decl_id from the DeclIdToTClass map
3995 if (cl->fClassInfo) {
3997 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3998 // Test again as another thread may have set fClassInfo to nullptr.
3999 if (TClinginfo) {
4000 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4001 }
4002 delete TClinginfo;
4003 cl->fClassInfo = nullptr;
4004 }
4005 return;
4006 }
4007
4009 if (cl->fClassInfo && !reload) {
4010 return;
4011 }
4012 //Remove the decl_id from the DeclIdToTClass map
4013 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4014 if (TClinginfo) {
4015 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4016 }
4017 delete TClinginfo;
4018 cl->fClassInfo = nullptr;
4019 std::string name(cl->GetName());
4020
4021 auto SetWithoutClassInfoState = [](TClass *cl)
4022 {
4023 if (cl->fState != TClass::kHasTClassInit) {
4024 if (cl->fStreamerInfo->GetEntries() != 0) {
4026 } else {
4028 }
4029 }
4030 };
4031 // Handle the special case of 'tuple' where we ignore the real implementation
4032 // details and just overlay a 'simpler'/'simplistic' version that is easy
4033 // for the I/O to understand and handle.
4034 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4035 if (!reload)
4036 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
4037 if (reload || name.empty()) {
4038 // We could not generate the alternate
4039 SetWithoutClassInfoState(cl);
4040 return;
4041 }
4042 }
4043
4044 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4045 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4046 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4047 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4048 // TClingClassInfoReadOnly.
4049 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4050 if (!info->IsValid()) {
4051 SetWithoutClassInfoState(cl);
4052 delete info;
4053 return;
4054 }
4055 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4056 // In case a class contains an external enum, the enum will be seen as a
4057 // class. We must detect this special case and make the class a Zombie.
4058 // Here we assume that a class has at least one method.
4059 // We can NOT call TClass::Property from here, because this method
4060 // assumes that the TClass is well formed to do a lot of information
4061 // caching. The method SetClassInfo (i.e. here) is usually called during
4062 // the building phase of the TClass, hence it is NOT well formed yet.
4063 Bool_t zombieCandidate = kFALSE;
4064 if (
4065 info->IsValid() &&
4066 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4067 ) {
4068 zombieCandidate = kTRUE;
4069 }
4070 if (!info->IsLoaded()) {
4071 if (info->Property() & (kIsNamespace)) {
4072 // Namespaces can have info but no corresponding CINT dictionary
4073 // because they are auto-created if one of their contained
4074 // classes has a dictionary.
4075 zombieCandidate = kTRUE;
4076 }
4077 // this happens when no dictionary is available
4078 delete info;
4079 cl->fClassInfo = nullptr;
4080 }
4081 if (zombieCandidate && !cl->GetCollectionType()) {
4082 cl->MakeZombie();
4083 }
4084 // If we reach here, the info was valid (See early returns).
4085 if (cl->fState != TClass::kHasTClassInit) {
4086 if (cl->fClassInfo) {
4089 } else {
4090// if (TClassEdit::IsSTLCont(cl->GetName()) {
4091// There will be an emulated collection proxy, is that the same?
4092// cl->fState = TClass::kEmulated;
4093// } else {
4094 if (cl->fStreamerInfo->GetEntries() != 0) {
4096 } else {
4098 }
4099// }
4100 }
4101 }
4102 if (cl->fClassInfo) {
4103 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4104 }
4105}
4106
4107////////////////////////////////////////////////////////////////////////////////
4108/// Checks if an entity with the specified name is defined in Cling.
4109/// Returns kUnknown if the entity is not defined.
4110/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4111/// Returns kKnown if the entity is defined.
4112///
4113/// By default, structs, namespaces, classes, enums and unions are looked for.
4114/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4115/// namespaces only are considered. I.e. if the name is an enum or a union,
4116/// the returned value is false.
4117///
4118/// In the case where the class is not loaded and belongs to a namespace
4119/// or is nested, looking for the full class name is outputting a lots of
4120/// (expected) error messages. Currently the only way to avoid this is to
4121/// specifically check that each level of nesting is already loaded.
4122/// In case of templates the idea is that everything between the outer
4123/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4124
4126TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4127{
4129 static const char *anonEnum = "anonymous enum ";
4130 static const int cmplen = strlen(anonEnum);
4131
4132 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4133 return kUnknown;
4134 }
4135
4136 // Do not turn on the AutoLoading if it is globally off.
4137 autoload = autoload && IsClassAutoLoadingEnabled();
4138
4139 // Avoid the double search below in case the name is a fundamental type
4140 // or typedef to a fundamental type.
4141 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4142 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4143
4144 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4145 && fundType->GetType() > 0) {
4146 // Fundamental type, no a class.
4147 return kUnknown;
4148 }
4149
4150 // Migrated from within TClass::GetClass
4151 // If we want to know if a class or a namespace with this name exists in the
4152 // interpreter and this is an enum in the type system, before or after loading
4153 // according to the autoload function argument, return kUnknown.
4154 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4155 return kUnknown;
4156
4157 const char *classname = name;
4158
4159 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4160 class MaybeSuspendAutoLoadParse {
4161 int fStoreAutoLoad = 0;
4162 int fStoreAutoParse = 0;
4163 bool fSuspendedAutoParse = false;
4164 public:
4165 MaybeSuspendAutoLoadParse(int autoload) {
4166 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4167 }
4168
4169 void SuspendAutoParsing() {
4170 fSuspendedAutoParse = true;
4171 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4172 }
4173
4174 ~MaybeSuspendAutoLoadParse() {
4175 if (fSuspendedAutoParse)
4176 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4177 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4178 }
4179 };
4180
4181 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4182 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4183 autoLoadParseRAII.SuspendAutoParsing();
4184
4185 // First we want to check whether the decl exist, but _without_
4186 // generating any template instantiation. However, the lookup
4187 // still will create a forward declaration of the class template instance
4188 // if it exist. In this case, the return value of findScope will still
4189 // be zero but the type will be initialized.
4190 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4191 // this forward declaration.
4192 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4193 const clang::Type *type = nullptr;
4194 const clang::Decl *decl
4195 = lh.findScope(classname,
4196 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4197 : cling::LookupHelper::NoDiagnostics,
4198 &type, /* intantiateTemplate= */ false );
4199 if (!decl) {
4200 std::string buf = TClassEdit::InsertStd(classname);
4201 decl = lh.findScope(buf,
4202 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4203 : cling::LookupHelper::NoDiagnostics,
4204 &type,false);
4205 }
4206
4207 if (type) {
4208 // If decl==0 and the type is valid, then we have a forward declaration.
4209 if (!decl) {
4210 // If we have a forward declaration for a class template instantiation,
4211 // we want to ignore it if it was produced/induced by the call to
4212 // findScope, however we can not distinguish those from the
4213 // instantiation induce by 'soft' use (and thus also induce by the
4214 // same underlying code paths)
4215 // ['soft' use = use not requiring a complete definition]
4216 // So to reduce the amount of disruption to the existing code we
4217 // would just ignore those for STL collection, for which we really
4218 // need to have the compiled collection proxy (and thus the TClass
4219 // bootstrap).
4220 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4221 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4222 (type->getAsCXXRecordDecl());
4223 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4224 // Since the point of instantiation is invalid, we 'guess' that
4225 // the 'instantiation' of the forwarded type appended in
4226 // findscope.
4227 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4228 // For STL Collection we return kUnknown.
4229 return kUnknown;
4230 }
4231 }
4232 }
4234 if (!tci.IsValid()) {
4235 return kUnknown;
4236 }
4237 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4239
4240 if (tci.Property() & propertiesMask) {
4241 bool hasClassDefInline = false;
4242 if (isClassOrNamespaceOnly) {
4243 // We do not need to check for ClassDefInline when this is called from
4244 // TClass::Init, we only do it for the call from TClass::GetClass.
4245 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4246 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4247
4248 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4249 int lineNumber = 0;
4250 bool success = false;
4251 std::tie(success, lineNumber) =
4252 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4253 hasClassDefInline = success && (lineNumber == -1);
4254 }
4255 }
4256
4257 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4258 // , hasClassDefInline);
4259
4260 // We are now sure that the entry is not in fact an autoload entry.
4261 if (hasClassDefInline)
4262 return kWithClassDefInline;
4263 else
4264 return kKnown;
4265 } else {
4266 // We are now sure that the entry is not in fact an autoload entry.
4267 return kUnknown;
4268 }
4269 }
4270
4271 if (decl)
4272 return kKnown;
4273 else
4274 return kUnknown;
4275
4276 // Setting up iterator part of TClingTypedefInfo is too slow.
4277 // Copy the lookup code instead:
4278 /*
4279 TClingTypedefInfo t(fInterpreter, name);
4280 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4281 delete[] classname;
4282 return kTRUE;
4283 }
4284 */
4285
4286// const clang::Decl *decl = lh.findScope(name);
4287// if (!decl) {
4288// std::string buf = TClassEdit::InsertStd(name);
4289// decl = lh.findScope(buf);
4290// }
4291
4292// return (decl);
4293}
4294
4295////////////////////////////////////////////////////////////////////////////////
4296/// Return true if there is a class template by the given name ...
4297
4299{
4300 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4301 // Interpreter transaction ahead, needs locking
4303 const clang::Decl *decl
4304 = lh.findClassTemplate(name,
4305 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4306 : cling::LookupHelper::NoDiagnostics);
4307 if (!decl) {
4308 std::string strname = "std::";
4309 strname += name;
4310 decl = lh.findClassTemplate(strname,
4311 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4312 : cling::LookupHelper::NoDiagnostics);
4313 }
4314 return nullptr != decl;
4315}
4316
4317////////////////////////////////////////////////////////////////////////////////
4318/// Create list of pointers to base class(es) for TClass cl.
4319
4321{
4323 if (cl->fBase) {
4324 return;
4325 }
4327 if (!tci) return;
4329 TList *listOfBase = new TList;
4330 while (t.Next()) {
4331 // if name cannot be obtained no use to put in list
4332 if (t.IsValid() && t.Name()) {
4334 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4335 }
4336 }
4337 // Now that is complete, publish it.
4338 cl->fBase = listOfBase;
4339}
4340
4341////////////////////////////////////////////////////////////////////////////////
4342/// Create list of pointers to enums for TClass cl.
4343
4344void TCling::LoadEnums(TListOfEnums& enumList) const
4345{
4347
4348 const Decl * D;
4349 TClass* cl = enumList.GetClass();
4350 if (cl) {
4351 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4352 }
4353 else {
4354 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4355 }
4356 // Iterate on the decl of the class and get the enums.
4357 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4358 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4359 // Collect all contexts of the namespace.
4360 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4361 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4362 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4363 declIter != declEnd; ++declIter) {
4364 // Iterate on all decls for each context.
4365 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4366 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4367 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4368 // Get name of the enum type.
4369 std::string buf;
4370 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4371 llvm::raw_string_ostream stream(buf);
4372 // Don't trigger fopen of the source file to count lines:
4373 Policy.AnonymousTagLocations = false;
4374 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4375 stream.flush();
4376 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4377 if (!buf.empty()) {
4378 const char* name = buf.c_str();
4379 // Add the enum to the list of loaded enums.
4380 enumList.Get(ED, name);
4381 }
4382 }
4383 }
4384 }
4385 }
4386}
4387
4388////////////////////////////////////////////////////////////////////////////////
4389/// Create list of pointers to function templates for TClass cl.
4390
4392{
4394
4395 const Decl * D;
4396 TListOfFunctionTemplates* funcTempList;
4397 if (cl) {
4398 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4399 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4400 }
4401 else {
4402 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4403 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4404 }
4405 // Iterate on the decl of the class and get the enums.
4406 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4407 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4408 // Collect all contexts of the namespace.
4409 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4410 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4411 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4412 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4413 // Iterate on all decls for each context.
4414 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4415 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4416 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4417 funcTempList->Get(FTD);
4418 }
4419 }
4420 }
4421 }
4422}
4423
4424////////////////////////////////////////////////////////////////////////////////
4425/// Get the scopes representing using declarations of namespace
4426
4427std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4428{
4430 return ci->GetUsingNamespaces();
4431}
4432
4433////////////////////////////////////////////////////////////////////////////////
4434/// Create list of pointers to data members for TClass cl.
4435/// This is now a nop. The creation and updating is handled in
4436/// TListOfDataMembers.
4437
4439{
4440}
4441
4442////////////////////////////////////////////////////////////////////////////////
4443/// Create list of pointers to methods for TClass cl.
4444/// This is now a nop. The creation and updating is handled in
4445/// TListOfFunctions.
4446
4448{
4449}
4450
4451////////////////////////////////////////////////////////////////////////////////
4452/// Update the list of pointers to method for TClass cl
4453/// This is now a nop. The creation and updating is handled in
4454/// TListOfFunctions.
4455
4457{
4458}
4459
4460////////////////////////////////////////////////////////////////////////////////
4461/// Update the list of pointers to data members for TClass cl
4462/// This is now a nop. The creation and updating is handled in
4463/// TListOfDataMembers.
4464
4466{
4467}
4468
4469////////////////////////////////////////////////////////////////////////////////
4470/// Create list of pointers to method arguments for TMethod m.
4471
4473{
4475 if (m->fMethodArgs) {
4476 return;
4477 }
4478 TList *arglist = new TList;
4480 while (t.Next()) {
4481 if (t.IsValid()) {
4483 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4484 }
4485 }
4486 m->fMethodArgs = arglist;
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Return whether we are waiting for more input either because the collected
4491/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4492
4494{
4495 return fMetaProcessor->awaitingMoreInput();
4496}
4497
4498////////////////////////////////////////////////////////////////////////////////
4499/// Generate a TClass for the given class.
4500/// Since the caller has already check the ClassInfo, let it give use the
4501/// result (via the value of emulation) rather than recalculate it.
4502
4503TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4504{
4505// For now the following line would lead to the (unwanted) instantiation
4506// of class template. This could/would need to be resurrected only if
4507// we re-introduce so sort of automatic instantiation. However this would
4508// have to include carefull look at the template parameter to avoid
4509// creating instance we can not really use (if the parameter are only forward
4510// declaration or do not have all the necessary interfaces).
4511
4512 // TClingClassInfo tci(fInterpreter, classname);
4513 // if (1 || !tci.IsValid()) {
4514
4515 Version_t version = 1;
4516 if (TClassEdit::IsSTLCont(classname)) {
4517 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4518 }
4520 TClass *cl = new TClass(classname, version, silent);
4521 if (emulation) {
4523 } else {
4524 // Set the class version if the class is versioned.
4525 // Note that we cannot just call CLASS::Class_Version() as we might not have
4526 // an execution engine (when invoked from rootcling).
4527
4528 // Do not call cl->GetClassVersion(), it has side effects!
4529 Version_t oldvers = cl->fClassVersion;
4530 if (oldvers == version && cl->GetClassInfo()) {
4531 // We have a version and it might need an update.
4533 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4534 // Namespaces don't have class versions.
4535 return cl;
4536 }
4537 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4540 if (!mi.IsValid()) {
4541 if (cl->TestBit(TClass::kIsTObject)) {
4542 Error("GenerateTClass",
4543 "Cannot find %s::Class_Version()! Class version might be wrong.",
4544 cl->GetName());
4545 }
4546 return cl;
4547 }
4548 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4549 *fInterpreter);
4550 if (newvers == -1) {
4551 // Didn't manage to determine the class version from the AST.
4552 // Use runtime instead.
4553 if ((mi.Property() & kIsStatic)
4554 && !fInterpreter->isInSyntaxOnlyMode()) {
4555 // This better be a static function.
4557 callfunc.SetFunc(&mi);
4558 newvers = callfunc.ExecInt(nullptr);
4559 } else {
4560 Error("GenerateTClass",
4561 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4562 cl->GetName());
4563 }
4564 }
4565 if (newvers != oldvers) {
4566 cl->fClassVersion = newvers;
4567 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4568 }
4569 }
4570 }
4571
4572 return cl;
4573
4574// } else {
4575// return GenerateTClass(&tci,silent);
4576// }
4577}
4578
4579#if 0
4580////////////////////////////////////////////////////////////////////////////////
4581
4582static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4583{
4584 includes += info->FileName();
4585
4586 const clang::ClassTemplateSpecializationDecl *templateCl
4587 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4588 if (templateCl) {
4589 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4590 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4591 if (arg.getKind() == clang::TemplateArgument::Type) {
4592 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4593
4594 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4595 // We really need a header file.
4596 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4597 if (argdecl) {
4598 includes += ";";
4599 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4600 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4601 } else {
4602 std::string Result;
4603 llvm::raw_string_ostream OS(Result);
4604 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4605 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4606 }
4607 }
4608 }
4609 }
4610 }
4611}
4612#endif
4613
4614////////////////////////////////////////////////////////////////////////////////
4615/// Generate a TClass for the given class.
4616
4617TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4618{
4619 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4620 if (!info || !info->IsValid()) {
4621 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4622 return nullptr;
4623 }
4624 // We are in the case where we have AST nodes for this class.
4625 TClass *cl = nullptr;
4626 std::string classname;
4627 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4628 if (TClassEdit::IsSTLCont(classname)) {
4629#if 0
4630 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4631 // We need to build up the list of required headers, by
4632 // looking at each template arguments.
4633 TString includes;
4634 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4635
4636 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4637 // 0 means success.
4638 cl = TClass::LoadClass(classnam.c_str(), silent);
4639 if (cl == 0) {
4640 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4641 }
4642 }
4643#endif
4644 if (cl == nullptr) {
4645 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4646 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4648 }
4649 } else {
4650 // For regular class, just create a TClass on the fly ...
4651 // Not quite useful yet, but that what CINT used to do anyway.
4652 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4653 }
4654 // Add the new TClass to the map of declid and TClass*.
4655 if (cl) {
4657 }
4658 return cl;
4659}
4660
4661////////////////////////////////////////////////////////////////////////////////
4662/// Generate the dictionary for the C++ classes listed in the first
4663/// argument (in a semi-colon separated list).
4664/// 'includes' contains a semi-colon separated list of file to
4665/// `#include` in the dictionary.
4666/// For example:
4667/// ~~~ {.cpp}
4668/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4669/// ~~~
4670/// or
4671/// ~~~ {.cpp}
4672/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4673/// ~~~
4674
4675Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4676{
4677 if (classes == nullptr || classes[0] == 0) {
4678 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4679 return 0;
4680 }
4681 // Split the input list
4682 std::vector<std::string> listClasses;
4683 for (
4684 const char* current = classes, *prev = classes;
4685 *current != 0;
4686 ++current
4687 ) {
4688 if (*current == ';') {
4689 listClasses.push_back(std::string(prev, current - prev));
4690 prev = current + 1;
4691 }
4692 else if (*(current + 1) == 0) {
4693 listClasses.push_back(std::string(prev, current + 1 - prev));
4694 prev = current + 1;
4695 }
4696 }
4697 std::vector<std::string> listIncludes;
4698 if (!includes)
4699 includes = "";
4700 for (
4701 const char* current = includes, *prev = includes;
4702 *current != 0;
4703 ++current
4704 ) {
4705 if (*current == ';') {
4706 listIncludes.push_back(std::string(prev, current - prev));
4707 prev = current + 1;
4708 }
4709 else if (*(current + 1) == 0) {
4710 listIncludes.push_back(std::string(prev, current + 1 - prev));
4711 prev = current + 1;
4712 }
4713 }
4714 // Generate the temporary dictionary file
4715 return !TCling_GenerateDictionary(listClasses, listIncludes,
4716 std::vector<std::string>(), std::vector<std::string>());
4717}
4718
4719////////////////////////////////////////////////////////////////////////////////
4720/// Return pointer to cling Decl of global/static variable that is located
4721/// at the address given by addr.
4722
4723TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4724{
4726 DeclId_t d;
4727 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4728
4729 // Could trigger deserialization of decls.
4730 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4731
4732 if (cl) {
4733 d = cl->GetDataMember(name);
4734 // We check if the decl of the data member has an annotation which indicates
4735 // an ioname.
4736 // In case this is true, if the name requested is not the ioname, we
4737 // return 0, as if the member did not exist. In some sense we override
4738 // the information in the TClassInfo instance, isolating the typesystem in
4739 // TClass from the one in the AST.
4740 if (const ValueDecl* decl = (const ValueDecl*) d){
4741 std::string ioName;
4742 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4743 if (hasIoName && ioName != name) return nullptr;
4744 }
4745 return d;
4746 }
4747 // We are looking up for something on the TU scope.
4748 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4749 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4750 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4751 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4752 // are only fulfilling ROOT's understanding for a Data Member.
4753 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4754 // similar as below.
4755 using namespace clang;
4756 Sema& SemaR = fInterpreter->getSema();
4757 DeclarationName DName = &SemaR.Context.Idents.get(name);
4758
4759 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4760 Sema::ForExternalRedeclaration);
4761
4762 cling::utils::Lookup::Named(&SemaR, R);
4763
4764 LookupResult::Filter F = R.makeFilter();
4765 // Filter the data-member looking decls.
4766 while (F.hasNext()) {
4767 NamedDecl *D = F.next();
4768 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4769 isa<IndirectFieldDecl>(D))
4770 continue;
4771 F.erase();
4772 }
4773 F.done();
4774
4775 if (R.isSingleResult())
4776 return R.getFoundDecl();
4777 return nullptr;
4778}
4779
4780////////////////////////////////////////////////////////////////////////////////
4781/// Return pointer to cling Decl of global/static variable that is located
4782/// at the address given by addr.
4783
4785{
4787
4788 const clang::Decl* possibleEnum = nullptr;
4789 // FInd the context of the decl.
4790 if (cl) {
4792 if (cci) {
4793 const clang::DeclContext* dc = nullptr;
4794 if (const clang::Decl* D = cci->GetDecl()) {
4795 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4796 dc = dyn_cast<clang::RecordDecl>(D);
4797 }
4798 }
4799 if (dc) {
4800 // If it is a data member enum.
4801 // Could trigger deserialization of decls.
4802 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4803 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4804 } else {
4805 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4806 }
4807 }
4808 } else {
4809 // If it is a global enum.
4810 // Could trigger deserialization of decls.
4811 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4812 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4813 }
4814 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4815 && isa<clang::EnumDecl>(possibleEnum)) {
4816 return possibleEnum;
4817 }
4818 return nullptr;
4819}
4820
4821////////////////////////////////////////////////////////////////////////////////
4822/// Return pointer to cling DeclId for a global value
4823
4824TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4825{
4826 if (!gv) return nullptr;
4827
4828 llvm::StringRef mangled_name = gv->getName();
4829
4830 int err = 0;
4831 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4832 if (err) {
4833 if (err == -2) {
4834 // It might simply be an unmangled global name.
4835 DeclId_t d;
4837 d = gcl.GetDataMember(mangled_name.str().c_str());
4838 return d;
4839 }
4840 return nullptr;
4841 }
4842
4843 std::string scopename(demangled_name_c);
4844 free(demangled_name_c);
4845
4846 //
4847 // Separate out the class or namespace part of the
4848 // function name.
4849 //
4850 std::string dataname;
4851
4852 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4853 scopename.erase(0, sizeof("typeinfo for ")-1);
4854 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4855 scopename.erase(0, sizeof("vtable for ")-1);
4856 } else {
4857 // See if it is a function
4858 std::string::size_type pos = scopename.rfind('(');
4859 if (pos != std::string::npos) {
4860 return nullptr;
4861 }
4862 // Separate the scope and member name
4863 pos = scopename.rfind(':');
4864 if (pos != std::string::npos) {
4865 if ((pos != 0) && (scopename[pos-1] == ':')) {
4866 dataname = scopename.substr(pos+1);
4867 scopename.erase(pos-1);
4868 }
4869 } else {
4870 scopename.clear();
4871 dataname = scopename;
4872 }
4873 }
4874 //fprintf(stderr, "name: '%s'\n", name.c_str());
4875 // Now we have the class or namespace name, so do the lookup.
4876
4877
4878 DeclId_t d;
4879 if (scopename.size()) {
4880 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4881 d = cl.GetDataMember(dataname.c_str());
4882 }
4883 else {
4885 d = gcl.GetDataMember(dataname.c_str());
4886 }
4887 return d;
4888}
4889
4890////////////////////////////////////////////////////////////////////////////////
4891/// NOT IMPLEMENTED.
4892
4894{
4895 Error("GetDataMemberWithValue()", "not implemented");
4896 return nullptr;
4897}
4898
4899////////////////////////////////////////////////////////////////////////////////
4900/// Return pointer to cling DeclId for a data member with a given name.
4901
4903{
4904 // NOT IMPLEMENTED.
4905 Error("GetDataMemberAtAddr()", "not implemented");
4906 return nullptr;
4907}
4908
4909////////////////////////////////////////////////////////////////////////////////
4910/// Return the cling mangled name for a method of a class with parameters
4911/// params (params is a string of actual arguments, not formal ones). If the
4912/// class is 0 the global function list will be searched.
4913
4914TString TCling::GetMangledName(TClass* cl, const char* method,
4915 const char* params, Bool_t objectIsConst /* = kFALSE */)
4916{
4919 if (cl) {
4921 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4922 &offset);
4923 }
4924 else {
4927 func.SetFunc(&gcl, method, params, &offset);
4928 }
4930 if (!mi) return "";
4931 TString mangled_name( mi->GetMangledName() );
4932 delete mi;
4933 return mangled_name;
4934}
4935
4936////////////////////////////////////////////////////////////////////////////////
4937/// Return the cling mangled name for a method of a class with a certain
4938/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4939/// list will be searched.
4940
4942 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4943 EFunctionMatchMode mode /* = kConversionMatch */)
4944{
4946 if (cl) {
4947 return ((TClingClassInfo*)cl->GetClassInfo())->
4948 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4949 }
4951 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4952}
4953
4954////////////////////////////////////////////////////////////////////////////////
4955/// Return pointer to cling interface function for a method of a class with
4956/// parameters params (params is a string of actual arguments, not formal
4957/// ones). If the class is 0 the global function list will be searched.
4958
4959void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4960 const char* params, Bool_t objectIsConst /* = kFALSE */)
4961{
4964 if (cl) {
4966 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4967 &offset);
4968 }
4969 else {
4972 func.SetFunc(&gcl, method, params, &offset);
4973 }
4974 return (void*) func.InterfaceMethod();
4975}
4976
4977////////////////////////////////////////////////////////////////////////////////
4978/// Return pointer to cling interface function for a method of a class with
4979/// a certain name.
4980
4981TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4982{
4984 DeclId_t f;
4985 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4986 if (cl) {
4987 f = cl->GetMethod(method).GetDeclId();
4988 }
4989 else {
4991 f = gcl.GetMethod(method).GetDeclId();
4992 }
4993 return f;
4994
4995}
4996
4997////////////////////////////////////////////////////////////////////////////////
4998/// Insert overloads of name in cl to res.
4999
5000void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5001 std::vector<DeclId_t>& res) const
5002{
5003 clang::Sema& S = fInterpreter->getSema();
5004 clang::ASTContext& Ctx = S.Context;
5005 const clang::Decl* CtxDecl
5006 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5007 Ctx.getTranslationUnitDecl();
5008 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5009 const clang::DeclContext* DeclCtx = RecDecl;
5010
5011 if (!DeclCtx)
5012 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5013 if (!DeclCtx) return;
5014
5015 clang::DeclarationName DName;
5016 // The DeclarationName is funcname, unless it's a ctor or dtor.
5017 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5018
5019 if (RecDecl) {
5020 if (RecDecl->getNameAsString() == funcname) {
5021 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5022 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5023 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5024 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5025 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5026 } else {
5027 DName = &Ctx.Idents.get(funcname);
5028 }
5029 } else {
5030 DName = &Ctx.Idents.get(funcname);
5031 }
5032
5033 // NotForRedeclaration: we want to find names in inline namespaces etc.
5034 clang::LookupResult R(S, DName, clang::SourceLocation(),
5035 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5036 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5037 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5038 if (R.empty()) return;
5039 R.resolveKind();
5040 res.reserve(res.size() + (R.end() - R.begin()));
5041 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5042 IR != ER; ++IR) {
5043 if (const clang::FunctionDecl* FD
5044 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5045 if (!FD->getDescribedFunctionTemplate()) {
5046 res.push_back(FD);
5047 }
5048 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5049 // FIXME: multi-level using
5050 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5051 res.push_back(USD);
5052 }
5053 }
5054 }
5055}
5056
5057////////////////////////////////////////////////////////////////////////////////
5058/// Return pointer to cling interface function for a method of a class with
5059/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5060/// function list will be searched.
5061
5063 const char* proto,
5064 Bool_t objectIsConst /* = kFALSE */,
5065 EFunctionMatchMode mode /* = kConversionMatch */)
5066{
5068 void* f;
5069 if (cl) {
5070 f = ((TClingClassInfo*)cl->GetClassInfo())->
5071 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5072 }
5073 else {
5075 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5076 }
5077 return f;
5078}
5079
5080////////////////////////////////////////////////////////////////////////////////
5081/// Return pointer to cling DeclId for a method of a class with
5082/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5083/// function list will be searched.
5084
5085TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5086 const char* params,
5087 Bool_t objectIsConst /* = kFALSE */)
5088{
5090 DeclId_t f;
5091 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5092 if (cl) {
5093 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5094 }
5095 else {
5097 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5098 }
5099 return f;
5100}
5101
5102////////////////////////////////////////////////////////////////////////////////
5103/// Return pointer to cling interface function for a method of a class with
5104/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5105/// function list will be searched.
5106
5107TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5108 const char* proto,
5109 Bool_t objectIsConst /* = kFALSE */,
5110 EFunctionMatchMode mode /* = kConversionMatch */)
5111{
5113 DeclId_t f;
5114 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5115 if (cl) {
5116 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5117 }
5118 else {
5120 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5121 }
5122 return f;
5123}
5124
5125////////////////////////////////////////////////////////////////////////////////
5126/// Return pointer to cling interface function for a method of a class with
5127/// a certain name.
5128
5129TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5130{
5132 DeclId_t f;
5133 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5134 if (cl) {
5135 f = cl->GetFunctionTemplate(name);
5136 }
5137 else {
5139 f = gcl.GetFunctionTemplate(name);
5140 }
5141 return f;
5142
5143}
5144
5145////////////////////////////////////////////////////////////////////////////////
5146/// The 'name' is known to the interpreter, this function returns
5147/// the internal version of this name (usually just resolving typedefs)
5148/// This is used in particular to synchronize between the name used
5149/// by rootcling and by the run-time environment (TClass)
5150/// Return 0 if the name is not known.
5151
5152void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5153{
5154 output.clear();
5155
5157
5159 if (!cl.IsValid()) {
5160 return ;
5161 }
5162 if (full) {
5164 return;
5165 }
5166 // Well well well, for backward compatibility we need to act a bit too
5167 // much like CINT.
5170
5171 return;
5172}
5173
5174////////////////////////////////////////////////////////////////////////////////
5175/// Execute a global function with arguments params.
5176///
5177/// FIXME: The cint-based version of this code does not check if the
5178/// SetFunc() call works, and does not do any real checking
5179/// for errors from the Exec() call. It did fetch the most
5180/// recent cint security error and return that in error, but
5181/// this does not really translate well to cling/clang. We
5182/// should enhance these interfaces so that we can report
5183/// compilation and runtime errors properly.
5184
5185void TCling::Execute(const char* function, const char* params, int* error)
5186{
5188 if (error) {
5189 *error = TInterpreter::kNoError;
5190 }
5192 Longptr_t offset = 0L;
5194 func.SetFunc(&cl, function, params, &offset);
5195 func.Exec(nullptr);
5196}
5197
5198////////////////////////////////////////////////////////////////////////////////
5199/// Execute a method from class cl with arguments params.
5200///
5201/// FIXME: The cint-based version of this code does not check if the
5202/// SetFunc() call works, and does not do any real checking
5203/// for errors from the Exec() call. It did fetch the most
5204/// recent cint security error and return that in error, but
5205/// this does not really translate well to cling/clang. We
5206/// should enhance these interfaces so that we can report
5207/// compilation and runtime errors properly.
5208
5209void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5210 const char* params, Bool_t objectIsConst, int* error)
5211{
5213 if (error) {
5214 *error = TInterpreter::kNoError;
5215 }
5216 // If the actual class of this object inherits 2nd (or more) from TObject,
5217 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5218 // hence gInterpreter->Execute will improperly correct the offset.
5219 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5220 Longptr_t offset = 0L;
5222 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5223 void* address = (void*)((Longptr_t)addr + offset);
5224 func.Exec(address);
5225}
5226
5227////////////////////////////////////////////////////////////////////////////////
5228
5229void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5230 const char* params, int* error)
5231{
5232 Execute(obj,cl,method,params,false,error);
5233}
5234
5235////////////////////////////////////////////////////////////////////////////////
5236/// Execute a method from class cl with the arguments in array params
5237/// (params[0] ... params[n] = array of TObjString parameters).
5238/// Convert the TObjArray array of TObjString parameters to a character
5239/// string of comma separated parameters.
5240/// The parameters of type 'char' are enclosed in double quotes and all
5241/// internal quotes are escaped.
5242
5243void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5244 TObjArray* params, int* error)
5245{
5246 if (!method) {
5247 Error("Execute", "No method was defined");
5248 return;
5249 }
5250 TList* argList = method->GetListOfMethodArgs();
5251 // Check number of actual parameters against of expected formal ones
5252
5253 Int_t nparms = argList->LastIndex() + 1;
5254 Int_t argc = params ? params->GetEntries() : 0;
5255
5256 if (argc > nparms) {
5257 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5258 return;
5259 }
5260 if (nparms != argc) {
5261 // Let's see if the 'missing' argument are all defaulted.
5262 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5263 assert(nparms > 0);
5264
5265 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5266 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5267 // There is a default value for the first missing
5268 // argument, so we are fine.
5269 } else {
5270 Int_t firstDefault = -1;
5271 for (Int_t i = 0; i < nparms; i ++) {
5272 arg = (TMethodArg *) argList->At( i );
5273 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5274 firstDefault = i;
5275 break;
5276 }
5277 }
5278 if (firstDefault >= 0) {
5279 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);
5280 } else {
5281 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5282 }
5283 return;
5284 }
5285 }
5286
5287 const char* listpar = "";
5288 TString complete(10);
5289 if (params) {
5290 // Create a character string of parameters from TObjArray
5291 TIter next(params);
5292 for (Int_t i = 0; i < argc; i ++) {
5293 TMethodArg* arg = (TMethodArg*) argList->At(i);
5295 TObjString* nxtpar = (TObjString*) next();
5296 if (i) {
5297 complete += ',';
5298 }
5299 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5300 TString chpar('\"');
5301 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5302 // At this point we have to check if string contains \\"
5303 // and apply some more sophisticated parser. Not implemented yet!
5304 complete += chpar;
5305 complete += '\"';
5306 }
5307 else {
5308 complete += nxtpar->String();
5309 }
5310 }
5311 listpar = complete.Data();
5312 }
5313
5314 // And now execute it.
5316 if (error) {
5317 *error = TInterpreter::kNoError;
5318 }
5319 // If the actual class of this object inherits 2nd (or more) from TObject,
5320 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5321 // hence gInterpreter->Execute will improperly correct the offset.
5322 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5324 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5325 func.Init(*minfo);
5326 func.SetArgs(listpar);
5327 // Now calculate the 'this' pointer offset for the method
5328 // when starting from the class described by cl.
5329 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5330 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5331 void* address = (void*)((Longptr_t)addr + offset);
5332 func.Exec(address);
5333}
5334
5335////////////////////////////////////////////////////////////////////////////////
5336
5337void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5338 const void* args[] /*=0*/,
5339 int nargs /*=0*/,
5340 void* ret/*= 0*/) const
5341{
5342 if (!method) {
5343 Error("ExecuteWithArgsAndReturn", "No method was defined");
5344 return;
5345 }
5346
5347 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5348 TClingCallFunc func(*minfo);
5349 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5350}
5351
5352////////////////////////////////////////////////////////////////////////////////
5353/// Execute a cling macro.
5354
5356{
5358 fCurExecutingMacros.push_back(filename);
5360 fCurExecutingMacros.pop_back();
5361 return result;
5362}
5363
5364////////////////////////////////////////////////////////////////////////////////
5365/// Return the file name of the current un-included interpreted file.
5366/// See the documentation for GetCurrentMacroName().
5367
5369{
5370 Warning("GetTopLevelMacroName", "Must change return type!");
5371 return fCurExecutingMacros.back();
5372}
5373
5374////////////////////////////////////////////////////////////////////////////////
5375/// Return the file name of the currently interpreted file,
5376/// included or not. Example to illustrate the difference between
5377/// GetCurrentMacroName() and GetTopLevelMacroName():
5378/// ~~~ {.cpp}
5379/// void inclfile() {
5380/// std::cout << "In inclfile.C" << std::endl;
5381/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5382/// TCling::GetCurrentMacroName() << std::endl;
5383/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5384/// TCling::GetTopLevelMacroName() << std::endl;
5385/// }
5386/// ~~~
5387/// ~~~ {.cpp}
5388/// void mymacro() {
5389/// std::cout << "In mymacro.C" << std::endl;
5390/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5391/// TCling::GetCurrentMacroName() << std::endl;
5392/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5393/// TCling::GetTopLevelMacroName() << std::endl;
5394/// std::cout << " Now calling inclfile..." << std::endl;
5395/// gInterpreter->ProcessLine(".x inclfile.C");;
5396/// }
5397/// ~~~
5398/// Running mymacro.C will print:
5399///
5400/// ~~~ {.cpp}
5401/// root [0] .x mymacro.C
5402/// ~~~
5403/// In mymacro.C
5404/// ~~~ {.cpp}
5405/// TCling::GetCurrentMacroName() returns ./mymacro.C
5406/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5407/// ~~~
5408/// Now calling inclfile...
5409/// In inclfile.h
5410/// ~~~ {.cpp}
5411/// TCling::GetCurrentMacroName() returns inclfile.C
5412/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5413/// ~~~
5414
5416{
5417#if defined(R__MUST_REVISIT)
5418#if R__MUST_REVISIT(6,0)
5419 Warning("GetCurrentMacroName", "Must change return type!");
5420#endif
5421#endif
5422 return fCurExecutingMacros.back();
5423}
5424
5425////////////////////////////////////////////////////////////////////////////////
5426/// Return the absolute type of typeDesc.
5427/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5428/// You need to use the result immediately before it is being overwritten.
5429
5430const char* TCling::TypeName(const char* typeDesc)
5431{
5432 TTHREAD_TLS_DECL(std::string,t);
5433
5434 if (!strstr(typeDesc, "(*)(")) {
5435 const char *s = strchr(typeDesc, ' ');
5436 const char *template_start = strchr(typeDesc, '<');
5437 if (!strcmp(typeDesc, "long long")) {
5438 t = typeDesc;
5439 }
5440 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5441 t = typeDesc;
5442 }
5443 // s is the position of the second 'word' (if any)
5444 // except in the case of templates where there will be a space
5445 // just before any closing '>': eg.
5446 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5447 else if (s && (template_start == nullptr || (s < template_start))) {
5448 t = s + 1;
5449 }
5450 else {
5451 t = typeDesc;
5452 }
5453 }
5454 else {
5455 t = typeDesc;
5456 }
5457 auto l = t.length();
5458 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5459 --l;
5460 t.resize(l);
5461 return t.c_str(); // NOLINT
5462}
5463
5464static bool requiresRootMap(const char* rootmapfile)
5465{
5466 assert(rootmapfile && *rootmapfile);
5467
5468 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5469 libName.consume_back(".rootmap");
5470
5471 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5472}
5473
5474////////////////////////////////////////////////////////////////////////////////
5475/// Read and parse a rootmapfile in its new format, and return 0 in case of
5476/// success, -1 if the file has already been read, and -3 in case its format
5477/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5478/// error.
5479
5480int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5481{
5482 if (!(rootmapfile && *rootmapfile))
5483 return 0;
5484
5485 if (!requiresRootMap(rootmapfile))
5486 return 0; // success
5487
5488 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5489 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5490
5491 std::string rootmapfileNoBackslash(rootmapfile);
5492#ifdef _MSC_VER
5493 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5494#endif
5495 // Add content of a specific rootmap file
5496 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5497 return -1;
5498
5499 // Line 1 is `{ decls }`
5500 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5501
5502 std::ifstream file(rootmapfileNoBackslash);
5503 std::string line;
5504 line.reserve(200);
5505 std::string lib_name;
5506 line.reserve(100);
5507 bool newFormat = false;
5508 while (getline(file, line, '\n')) {
5509 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5510 file.close();
5511 return -3; // old format
5512 }
5513 newFormat = true;
5514
5515 if (line.compare(0, 9, "{ decls }") == 0) {
5516 // forward declarations
5517
5518 while (getline(file, line, '\n')) {
5519 if (line[0] == '[')
5520 break;
5521 if (!uniqueString) {
5522 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5523 rootmapfileNoBackslash.c_str());
5524 return -4;
5525 }
5526 if (!lineDirective.empty())
5527 uniqueString->Append(lineDirective);
5528 uniqueString->Append(line + '\n');
5529 }
5530 }
5531 const char firstChar = line[0];
5532 if (firstChar == '[') {
5533 // new section (library)
5534 auto brpos = line.find(']');
5535 if (brpos == string::npos)
5536 continue;
5537 lib_name = line.substr(1, brpos - 1);
5538 // Remove spaces at the beginning and at the end of the library name
5539 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5540 lib_name.erase(0, lib_name.find_first_not_of(' '));
5541 if (gDebug > 3) {
5542 TString lib_nameTstr(lib_name.c_str());
5543 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5544 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5545 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5546 if (wlib) {
5547 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5548 } else {
5549 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5550 }
5551 delete[] wlib;
5552 delete tokens;
5553 }
5554 } else {
5555 auto keyLenIt = keyLenMap.find(firstChar);
5556 if (keyLenIt == keyLenMap.end())
5557 continue;
5558 unsigned int keyLen = keyLenIt->second;
5559 // Do not make a copy, just start after the key
5560 const char *keyname = line.c_str() + keyLen;
5561 if (gDebug > 6)
5562 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5563 TEnvRec *isThere = fMapfile->Lookup(keyname);
5564 if (isThere) {
5565 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5566 if (firstChar == 'n') {
5567 if (gDebug > 3)
5568 Info("ReadRootmapFile",
5569 "While processing %s, namespace %s was found to be associated to %s although it is already "
5570 "associated to %s",
5571 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5572 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5573 lib_name += " ";
5574 lib_name += isThere->GetValue();
5575 fMapfile->SetValue(keyname, lib_name.c_str());
5576 } else if (!TClassEdit::IsSTLCont(keyname)) {
5577 Warning("ReadRootmapFile",
5578 "While processing %s, %s %s was found to be associated to %s although it is already "
5579 "associated to %s",
5580 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5581 isThere->GetValue());
5582 }
5583 } else { // the same key for the same lib
5584 if (gDebug > 3)
5585 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5586 rootmapfile, keyname, lib_name.c_str());
5587 }
5588 } else {
5589 fMapfile->SetValue(keyname, lib_name.c_str());
5590 }
5591 }
5592 }
5593 file.close();
5594 return 0;
5595}
5596
5597////////////////////////////////////////////////////////////////////////////////
5598/// Create a resource table and read the (possibly) three resource files,
5599/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5600/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5601/// can read additional user defined resource files by creating additional TEnv
5602/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5603/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5604/// case the home directory resides on an automounted remote file system
5605/// and one wants to avoid the file system from being mounted.
5606
5608{
5609 assert(requiresRootMap(name) && "We have a module!");
5610
5611 if (!requiresRootMap(name))
5612 return;
5613
5615
5617
5618 TString sname = "system";
5619 sname += name;
5620 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5621
5622 Int_t ret = ReadRootmapFile(s);
5623 if (ret == -3) // old format
5625 delete [] s;
5626 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5628 ret = ReadRootmapFile(s);
5629 if (ret == -3) // old format
5631 delete [] s;
5632 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5633 ret = ReadRootmapFile(name);
5634 if (ret == -3) // old format
5636 }
5637 } else {
5638 ret = ReadRootmapFile(name);
5639 if (ret == -3) // old format
5641 }
5642 fMapfile->IgnoreDuplicates(ignore);
5643}
5644
5645
5646namespace {
5647 using namespace clang;
5648
5649 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5650 // This class is to be considered an helper for AutoLoading.
5651 // It is a recursive visitor is used to inspect namespaces and specializations
5652 // coming from forward declarations in rootmaps and to set the external visible
5653 // storage flag for them.
5654 public:
5655 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5656 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5657 // We want to enable the external lookup for this namespace
5658 // because it may shadow the lookup of other names contained
5659 // in that namespace
5660
5661 nsDecl->setHasExternalVisibleStorage();
5662 fNSSet.insert(nsDecl);
5663 return true;
5664 }
5665 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5666 // We want to enable the external lookup for this specialization
5667 // because we can provide a definition for it!
5668 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5669 //SpecSet.insert(specDecl);
5670 specDecl->setHasExternalLexicalStorage();
5671
5672 // No need to recurse. On the contrary, recursing is actively harmful:
5673 // NOTE: must not recurse to prevent this visitor from triggering loading from
5674 // the external AST source (i.e. autoloading). This would be triggered right here,
5675 // before autoloading is even set up, as rootmap file parsing happens before that.
5676 // Even if autoloading is off and has no effect, triggering loading from external
5677 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5678 // from subsequent autoloads!
5679 return false;
5680 }
5681 private:
5682 std::unordered_set<const NamespaceDecl*>& fNSSet;
5683 };
5684}
5685
5686////////////////////////////////////////////////////////////////////////////////
5687/// Load map between class and library. If rootmapfile is specified a
5688/// specific rootmap file can be added (typically used by ACLiC).
5689/// In case of error -1 is returned, 0 otherwise.
5690/// The interpreter uses this information to automatically load the shared
5691/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5692
5693Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5694{
5695 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5696 return 0;
5697
5699
5700 // open the [system].rootmap files
5701 if (!fMapfile) {
5702 fMapfile = new TEnv();
5706 InitRootmapFile(".rootmap");
5707 }
5708
5709 // Prepare a list of all forward declarations for cling
5710 // For some experiments it is easily as big as 500k characters. To be on the
5711 // safe side, we go for 1M.
5712 TUniqueString uniqueString(1048576);
5713
5714 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5715 // A rootmap file must end with the string ".rootmap".
5716 TString ldpath = gSystem->GetDynamicPath();
5717 if (ldpath != fRootmapLoadPath) {
5718 fRootmapLoadPath = ldpath;
5719#ifdef WIN32
5720 TObjArray* paths = ldpath.Tokenize(";");
5721#else
5722 TObjArray* paths = ldpath.Tokenize(":");
5723#endif
5724 TString d;
5725 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5726 d = ((TObjString *)paths->At(i))->GetString();
5727 // check if directory already scanned
5728 Int_t skip = 0;
5729 for (Int_t j = 0; j < i; j++) {
5730 TString pd = ((TObjString *)paths->At(j))->GetString();
5731 if (pd == d) {
5732 skip++;
5733 break;
5734 }
5735 }
5736 if (!skip) {
5737 void* dirp = gSystem->OpenDirectory(d);
5738 if (dirp) {
5739 if (gDebug > 3) {
5740 Info("LoadLibraryMap", "%s", d.Data());
5741 }
5742 const char* f1;
5743 while ((f1 = gSystem->GetDirEntry(dirp))) {
5744 TString f = f1;
5745 if (f.EndsWith(".rootmap")) {
5746 TString p;
5747 p = d + "/" + f;
5749 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5750 if (gDebug > 4) {
5751 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5752 }
5753 Int_t ret = ReadRootmapFile(p, &uniqueString);
5754
5755 if (ret == 0)
5756 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5757 if (ret == -3) {
5758 // old format
5760 fRootmapFiles->Add(new TNamed(f, p));
5761 }
5762 }
5763 // else {
5764 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5765 // fRootmapFiles->FindObject(f)->ls();
5766 // }
5767 }
5768 }
5769 if (f.BeginsWith("rootmap")) {
5770 TString p;
5771 p = d + "/" + f;
5772 FileStat_t stat;
5773 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5774 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5775 }
5776 }
5777 }
5778 }
5779 gSystem->FreeDirectory(dirp);
5780 }
5781 }
5782 delete paths;
5783 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5784 return -1;
5785 }
5786 }
5787 if (rootmapfile && *rootmapfile) {
5788 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5789 if (res == 0) {
5790 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5791 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5792 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5793 }
5794 else if (res == -3) {
5795 // old format
5797 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5798 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5799 fMapfile->IgnoreDuplicates(ignore);
5800 }
5801 }
5802 TEnvRec* rec;
5803 TIter next(fMapfile->GetTable());
5804 while ((rec = (TEnvRec*) next())) {
5805 TString cls = rec->GetName();
5806 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5807 // get the first lib from the list of lib and dependent libs
5808 TString libs = rec->GetValue();
5809 if (libs == "") {
5810 continue;
5811 }
5812 TString delim(" ");
5813 TObjArray* tokens = libs.Tokenize(delim);
5814 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5815 // convert "@@" to "::", we used "@@" because TEnv
5816 // considers "::" a terminator
5817 cls.Remove(0, 8);
5818 cls.ReplaceAll("@@", "::");
5819 // convert "-" to " ", since class names may have
5820 // blanks and TEnv considers a blank a terminator
5821 cls.ReplaceAll("-", " ");
5822 if (gDebug > 6) {
5823 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5824 if (wlib) {
5825 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5826 }
5827 else {
5828 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5829 }
5830 delete[] wlib;
5831 }
5832 delete tokens;
5833 }
5834 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5835 cls.Remove(0, 8);
5836 // convert "-" to " ", since class names may have
5837 // blanks and TEnv considers a blank a terminator
5838 cls.ReplaceAll("-", " ");
5839 fInterpreter->declare(cls.Data());
5840 }
5841 }
5842
5843 // Process the forward declarations collected
5844 cling::Transaction* T = nullptr;
5845 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5846 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5847
5848 if (compRes!=cling::Interpreter::kSuccess){
5849 Warning("LoadLibraryMap",
5850 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5851 }
5852
5853 if (T) {
5854 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5855 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5856 if (declIt->m_DGR.isSingleDecl()) {
5857 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5858 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5859 evsAdder.TraverseDecl(D);
5860 }
5861 }
5862 }
5863 }
5864 }
5865
5866 // clear duplicates
5867
5868 return 0;
5869}
5870
5871////////////////////////////////////////////////////////////////////////////////
5872/// Scan again along the dynamic path for library maps. Entries for the loaded
5873/// shared libraries are unloaded first. This can be useful after reseting
5874/// the dynamic path through TSystem::SetDynamicPath()
5875/// In case of error -1 is returned, 0 otherwise.
5876
5878{
5881 return 0;
5882}
5883
5884////////////////////////////////////////////////////////////////////////////////
5885/// Reload the library map entries coming from all the loaded shared libraries,
5886/// after first unloading the current ones.
5887/// In case of error -1 is returned, 0 otherwise.
5888
5890{
5891 const TString sharedLibLStr = GetSharedLibs();
5892 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5893 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5894 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5895 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5896 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5897 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5898 if (ret < 0) {
5899 continue;
5900 }
5901 TString rootMapBaseStr = sharedLibBaseStr;
5902 if (sharedLibBaseStr.EndsWith(".dll")) {
5903 rootMapBaseStr.ReplaceAll(".dll", "");
5904 }
5905 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5906 rootMapBaseStr.ReplaceAll(".DLL", "");
5907 }
5908 else if (sharedLibBaseStr.EndsWith(".so")) {
5909 rootMapBaseStr.ReplaceAll(".so", "");
5910 }
5911 else if (sharedLibBaseStr.EndsWith(".sl")) {
5912 rootMapBaseStr.ReplaceAll(".sl", "");
5913 }
5914 else if (sharedLibBaseStr.EndsWith(".dl")) {
5915 rootMapBaseStr.ReplaceAll(".dl", "");
5916 }
5917 else if (sharedLibBaseStr.EndsWith(".a")) {
5918 rootMapBaseStr.ReplaceAll(".a", "");
5919 }
5920 else {
5921 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5922 delete sharedLibL;
5923 return -1;
5924 }
5925 rootMapBaseStr += ".rootmap";
5926 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5927 if (!rootMap) {
5928 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5929 delete[] rootMap;
5930 delete sharedLibL;
5931 return -1;
5932 }
5933 const Int_t status = LoadLibraryMap(rootMap);
5934 if (status < 0) {
5935 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5936 delete[] rootMap;
5937 delete sharedLibL;
5938 return -1;
5939 }
5940 delete[] rootMap;
5941 }
5942 delete sharedLibL;
5943 return 0;
5944}
5945
5946////////////////////////////////////////////////////////////////////////////////
5947/// Unload the library map entries coming from all the loaded shared libraries.
5948/// Returns 0 if succesful
5949
5951{
5952 const TString sharedLibLStr = GetSharedLibs();
5953 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5954 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5955 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5956 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5957 UnloadLibraryMap(sharedLibBaseStr);
5958 }
5959 delete sharedLibL;
5960 return 0;
5961}
5962
5963////////////////////////////////////////////////////////////////////////////////
5964/// Unload library map entries coming from the specified library.
5965/// Returns -1 in case no entries for the specified library were found,
5966/// 0 otherwise.
5967
5969{
5970 if (!fMapfile || !library || !*library) {
5971 return 0;
5972 }
5973 TString libname(library);
5974 Ssiz_t idx = libname.Last('.');
5975 if (idx != kNPOS) {
5976 libname.Remove(idx);
5977 }
5978 size_t len = libname.Length();
5979 TEnvRec *rec;
5980 TIter next(fMapfile->GetTable());
5982 Int_t ret = 0;
5983 while ((rec = (TEnvRec *) next())) {
5984 TString cls = rec->GetName();
5985 if (cls.Length() > 2) {
5986 // get the first lib from the list of lib and dependent libs
5987 TString libs = rec->GetValue();
5988 if (libs == "") {
5989 continue;
5990 }
5991 TString delim(" ");
5992 TObjArray* tokens = libs.Tokenize(delim);
5993 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5994 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5995 // convert "@@" to "::", we used "@@" because TEnv
5996 // considers "::" a terminator
5997 cls.Remove(0, 8);
5998 cls.ReplaceAll("@@", "::");
5999 // convert "-" to " ", since class names may have
6000 // blanks and TEnv considers a blank a terminator
6001 cls.ReplaceAll("-", " ");
6002 }
6003 if (!strncmp(lib, libname.Data(), len)) {
6004 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6005 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6006 ret = -1;
6007 }
6008 }
6009 delete tokens;
6010 }
6011 }
6012 if (ret >= 0) {
6013 TString library_rootmap(library);
6014 if (!library_rootmap.EndsWith(".rootmap"))
6015 library_rootmap.Append(".rootmap");
6016 TNamed* mfile = nullptr;
6017 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6018 fRootmapFiles->Remove(mfile);
6019 delete mfile;
6020 }
6022 }
6023 return ret;
6024}
6025
6026////////////////////////////////////////////////////////////////////////////////
6027/// Register the AutoLoading information for a class.
6028/// libs is a space separated list of libraries.
6029
6030Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6031{
6032 if (!cls || !*cls)
6033 return 0;
6034
6035 TString key = TString("Library.") + cls;
6036 // convert "::" to "@@", we used "@@" because TEnv
6037 // considers "::" a terminator
6038 key.ReplaceAll("::", "@@");
6039 // convert "-" to " ", since class names may have
6040 // blanks and TEnv considers a blank a terminator
6041 key.ReplaceAll(" ", "-");
6042
6044 if (!fMapfile) {
6045 fMapfile = new TEnv();
6047
6050
6051 InitRootmapFile(".rootmap");
6052 }
6053 //fMapfile->SetValue(key, libs);
6054 fMapfile->SetValue(cls, libs);
6055 return 1;
6056}
6057
6058////////////////////////////////////////////////////////////////////////////////
6059/// Demangle the name (from the typeinfo) and then request the class
6060/// via the usual name based interface (TClass::GetClass).
6061
6062TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6063{
6064 int err = 0;
6065 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6066 if (err) return nullptr;
6067 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6068 free(demangled_name);
6069 return theClass;
6070}
6071
6072////////////////////////////////////////////////////////////////////////////////
6073/// Load library containing the specified class. Returns 0 in case of error
6074/// and 1 in case if success.
6075
6076Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6077{
6078 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6079
6080 int err = 0;
6081 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6082 if (err) {
6083 return 0;
6084 }
6085
6086 std::string demangled_name(demangled_name_c);
6087 free(demangled_name_c);
6088
6089 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6090 // shortened name.
6092 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6093
6094 // No need to worry about typedef, they aren't any ... but there are
6095 // inlined namespaces ...
6096
6097 Int_t result = AutoLoad(demangled_name.c_str());
6098 if (result == 0) {
6099 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6100 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6101 }
6102
6103 return result;
6104}
6105
6106////////////////////////////////////////////////////////////////////////////////
6107// Get the list of 'published'/'known' library for the class and load them.
6109{
6110 Int_t status = 0;
6111
6112 // lookup class to find list of dependent libraries
6113 TString deplibs = gCling->GetClassSharedLibs(cls);
6114 if (!deplibs.IsNull()) {
6115 TString delim(" ");
6116 TObjArray* tokens = deplibs.Tokenize(delim);
6117 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6118 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6119 if (gROOT->LoadClass(cls, deplib) == 0) {
6120 if (gDebug > 0) {
6121 gCling->Info("TCling::AutoLoad",
6122 "loaded dependent library %s for %s", deplib, cls);
6123 }
6124 }
6125 else {
6126 gCling->Error("TCling::AutoLoad",
6127 "failure loading dependent library %s for %s",
6128 deplib, cls);
6129 }
6130 }
6131 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6132 if (lib && lib[0]) {
6133 if (gROOT->LoadClass(cls, lib) == 0) {
6134 if (gDebug > 0) {
6135 gCling->Info("TCling::AutoLoad",
6136 "loaded library %s for %s", lib, cls);
6137 }
6138 status = 1;
6139 }
6140 else {
6141 gCling->Error("TCling::AutoLoad",
6142 "failure loading library %s for %s", lib, cls);
6143 }
6144 }
6145 delete tokens;
6146 }
6147
6148 return status;
6149}
6150
6151////////////////////////////////////////////////////////////////////////////////
6152// Iterate through the data member of the class (either through the TProtoClass
6153// or through Cling) and trigger, recursively, the loading the necessary libraries.
6154// \note `cls` is expected to be already normalized!
6155// \returns 1 on success.
6156Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6157 bool nameIsNormalized)
6158{
6159 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6160 // has previously (within the same call to `AutoLoad()`) tried to load this class
6161 // and we are done, whether success or not, as it won't work better now than before,
6162 // because there is no additional information now compared to before.
6163 if (!visited.insert(std::string(cls)).second)
6164 return 1;
6165
6166 if (ShallowAutoLoadImpl(cls) == 0) {
6167 // If ShallowAutoLoadImpl() has an error, we have an error.
6168 return 0;
6169 }
6170
6171 // Now look through the TProtoClass to load the required library/dictionary
6172 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6173 for (auto element : proto->GetData()) {
6174 if (element->IsBasic())
6175 continue;
6176 const char *subtypename = element->GetTypeName();
6177 if (!TClassTable::GetDictNorm(subtypename)) {
6178 // Failure to load a dictionary is not (quite) a failure load
6179 // the top-level library. If we return false here, then
6180 // we would end up in a situation where the library and thus
6181 // the dictionary is loaded for "cls" but the TClass is
6182 // not created and/or marked as unavailable (in case where
6183 // AutoLoad is called from TClass::GetClass).
6184 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6185 }
6186 }
6187 return 1;
6188 }
6189
6190 // We found no TProtoClass for cls.
6191 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6192 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6193 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6194 {
6195 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6196 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6197 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6198 continue;
6199 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6200 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6201 // Failure to load a dictionary is not (quite) a failure load
6202 // the top-level library. See detailed comment in the TProtoClass
6203 // branch (above).
6204 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6205 }
6206 }
6207 gInterpreter->DataMemberInfo_Delete(memberinfo);
6208 }
6209 gInterpreter->ClassInfo_Delete(classinfo);
6210 return 1;
6211}
6212
6213////////////////////////////////////////////////////////////////////////////////
6214/// Load library containing the specified class. Returns 0 in case of error
6215/// and 1 in case if success.
6216
6217Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6218{
6219 // Prevent update to IsClassAutoloading between our check and our actions.
6221
6222 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6223 // rootcling (in *_rdict.pcm file generation) it is a no op.
6224 // FIXME: We should avoid calling autoload when we know we are not supposed
6225 // to and transform this check into an assert.
6227 // Never load any library from rootcling/genreflex.
6228 if (gDebug > 2) {
6229 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6230 }
6231 return 0;
6232 }
6233
6234 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6235
6237
6238 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6239 // The library is already loaded as the class's dictionary is known.
6240 // Return success.
6241 // Note: the name (cls) is expected to be normalized as it comes either
6242 // from a callbacks (that can/should calculate the normalized name from the
6243 // decl) or from TClass::GetClass (which does also calculate the normalized
6244 // name).
6245 return 1;
6246 }
6247
6248 if (gDebug > 2) {
6249 Info("TCling::AutoLoad",
6250 "Trying to autoload for %s", cls);
6251 }
6252
6253 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6254 if (gDebug > 2) {
6255 Info("TCling::AutoLoad",
6256 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6257 }
6258 return 0;
6259 }
6260 // Prevent the recursion when the library dictionary are loaded.
6261 SuspendAutoLoadingRAII autoLoadOff(this);
6262 // Try using externally provided callback first.
6263 if (fAutoLoadCallBack) {
6264 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6265 if (success)
6266 return success;
6267 }
6268
6269 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6270 // (when module are enabled) which might end up calling AutoParsing but
6271 // that should only be for the cases where the library has no generated pcm
6272 // and in that case a rootmap should be available.
6273 // This avoids a very costly operation (for generally no gain) but reduce the
6274 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6275 // file).
6276 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6277 std::unordered_set<std::string> visited;
6278 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6279}
6280
6281////////////////////////////////////////////////////////////////////////////////
6282/// Parse the payload or header.
6283
6284static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6285 Bool_t header,
6286 cling::Interpreter *interpreter)
6287{
6288 std::string code = gNonInterpreterClassDef ;
6289 if (!header) {
6290 // This is the complete header file content and not the
6291 // name of a header.
6292 code += what;
6293
6294 } else {
6295 code += ("#include \"");
6296 code += what;
6297 code += "\"\n";
6298 }
6299 code += ("#ifdef __ROOTCLING__\n"
6300 "#undef __ROOTCLING__\n"
6301 + gInterpreterClassDef +
6302 "#endif");
6303
6304 cling::Interpreter::CompilationResult cr;
6305 {
6306 // scope within which diagnostics are de-activated
6307 // For now we disable diagnostics because we saw them already at
6308 // dictionary generation time. That won't be an issue with the PCMs.
6309
6310 Sema &SemaR = interpreter->getSema();
6311 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6312 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6313
6314 #if defined(R__MUST_REVISIT)
6315 #if R__MUST_REVISIT(6,2)
6316 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6317 #endif
6318 #endif
6319
6320 cr = interpreter->parseForModule(code);
6321 }
6322 return cr;
6323}
6324
6325////////////////////////////////////////////////////////////////////////////////
6326/// Helper routine for TCling::AutoParse implementing the actual call to the
6327/// parser and looping over template parameters (if
6328/// any) and when they don't have a registered header to autoparse,
6329/// recurse over their template parameters.
6330///
6331/// Returns the number of header parsed.
6332
6333UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6334{
6335 // We assume the lock has already been taken.
6336 // R__LOCKGUARD(gInterpreterMutex);
6337
6338 Int_t nHheadersParsed = 0;
6339 unsigned long offset = 0;
6340 if (strncmp(cls, "const ", 6) == 0) {
6341 offset = 6;
6342 }
6343
6344 // Loop on the possible autoparse keys
6345 bool skipFirstEntry = false;
6346 std::vector<std::string> autoparseKeys;
6347 if (strchr(cls, '<')) {
6348 int nestedLoc = 0;
6349 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6350 // Check if we can skip the name of the template in the autoparses
6351 // Take all the scopes one by one. If all of them are in the AST, we do not
6352 // need to autoparse for that particular template.
6353 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6354 // autoparseKeys[0] is empty when the input is not a template instance.
6355 // The case strchr(cls, '<') != 0 but still not a template instance can
6356 // happens 'just' for string (GetSplit replaces the template by the short name
6357 // and then use that for thew splitting)
6358 TString templateName(autoparseKeys[0]);
6359 auto tokens = templateName.Tokenize("::");
6360 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6361 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6362 if (TClassEdit::IsStdClass(cls + offset))
6363 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6364 auto nTokens = tokens->GetEntriesFast();
6365 for (Int_t tk = 0; tk < nTokens; ++tk) {
6366 auto scopeObj = tokens->UncheckedAt(tk);
6367 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6368 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6369 // Check if we have multiple nodes in the AST with this name
6370 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6371 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6372 if (!previousScopeAsContext) break; // this is not a context
6373 }
6374 delete tokens;
6375 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6376 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6377 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6378 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6379 skipFirstEntry = templatedDecl->hasDefinition();
6380 }
6381 }
6382 }
6383
6384 }
6385 }
6386 if (topLevel) autoparseKeys.emplace_back(cls);
6387
6388 for (const auto & apKeyStr : autoparseKeys) {
6389 if (skipFirstEntry) {
6390 skipFirstEntry=false;
6391 continue;
6392 }
6393 if (apKeyStr.empty()) continue;
6394 const char *apKey = apKeyStr.c_str();
6395 std::size_t normNameHash(fStringHashFunction(apKey));
6396 // If the class was not looked up
6397 if (gDebug > 1) {
6398 Info("TCling::AutoParse",
6399 "Starting autoparse for %s\n", apKey);
6400 }
6401 if (fLookedUpClasses.insert(normNameHash).second) {
6402 auto const &iter = fClassesHeadersMap.find(normNameHash);
6403 if (iter != fClassesHeadersMap.end()) {
6404 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6405 fTransactionHeadersMap.insert({T,normNameHash});
6406 auto const &hNamesPtrs = iter->second;
6407 if (gDebug > 1) {
6408 Info("TCling::AutoParse",
6409 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6410 }
6411 for (auto & hName : hNamesPtrs) {
6412 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6413 if (0 != fPayloads.count(normNameHash)) {
6414 float initRSSval=0.f, initVSIZEval=0.f;
6415 (void) initRSSval; // Avoid unused var warning
6416 (void) initVSIZEval;
6417 if (gDebug > 0) {
6418 Info("AutoParse",
6419 "Parsing full payload for %s", apKey);
6420 ProcInfo_t info;
6421 gSystem->GetProcInfo(&info);
6422 initRSSval = 1e-3*info.fMemResident;
6423 initVSIZEval = 1e-3*info.fMemVirtual;
6424 }
6425 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6426 if (cRes != cling::Interpreter::kSuccess) {
6427 if (hName[0] == '\n')
6428 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6429 } else {
6430 fParsedPayloadsAddresses.insert(hName);
6431 nHheadersParsed++;
6432 if (gDebug > 0){
6433 ProcInfo_t info;
6434 gSystem->GetProcInfo(&info);
6435 float endRSSval = 1e-3*info.fMemResident;
6436 float endVSIZEval = 1e-3*info.fMemVirtual;
6437 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6438 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6439 }
6440 }
6441 } else if (!IsLoaded(hName)) {
6442 if (gDebug > 0) {
6443 Info("AutoParse",
6444 "Parsing single header %s", hName);
6445 }
6446 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6447 if (cRes != cling::Interpreter::kSuccess) {
6448 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6449 } else {
6450 nHheadersParsed++;
6451 }
6452 }
6453 }
6454 }
6455 else {
6456 // There is no header registered for this class, if this a
6457 // template, it will be instantiated if/when it is requested
6458 // and if we do no load/parse its components we might end up
6459 // not using an eventual specialization.
6460 if (strchr(apKey, '<')) {
6461 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6462 }
6463 }
6464 }
6465 }
6466
6467 return nHheadersParsed;
6468
6469}
6470
6471////////////////////////////////////////////////////////////////////////////////
6472/// Parse the headers relative to the class
6473/// Returns 1 in case of success, 0 in case of failure
6474
6475Int_t TCling::AutoParse(const char *cls)
6476{
6477 if (llvm::StringRef(cls).contains("(lambda)"))
6478 return 0;
6479
6482 return AutoLoad(cls);
6483 } else {
6484 return 0;
6485 }
6486 }
6487
6489
6490 if (gDebug > 1) {
6491 Info("TCling::AutoParse",
6492 "Trying to autoparse for %s", cls);
6493 }
6494
6495 // The catalogue of headers is in the dictionary
6497 && !gClassTable->GetDictNorm(cls)) {
6498 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6499 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6500 fInterpreter->getSema());
6501 AutoLoad(cls, true /*knowDictNotLoaded*/);
6502 }
6503
6504 // Prevent the recursion when the library dictionary are loaded.
6505 SuspendAutoLoadingRAII autoLoadOff(this);
6506
6507 // No recursive header parsing on demand; we require headers to be standalone.
6508 SuspendAutoParsing autoParseRAII(this);
6509
6510 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6511
6513
6514 return nHheadersParsed > 0 ? 1 : 0;
6515}
6516
6517// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6518// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6519// false if not.
6520bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6521{
6522 StringRef errMsg(errmessage);
6523 if (errMsg.contains("undefined symbol: ")) {
6524 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6525 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6526 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6527 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6528 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6529 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6530 return true;
6531 } else {
6532 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6533 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6534 return true;
6535 }
6536
6537 return false;
6538}
6539
6540////////////////////////////////////////////////////////////////////////////////
6541/// Autoload a library based on a missing symbol.
6542
6543void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6544 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6545
6546 // We have already loaded the library.
6547 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6548 return Addr;
6549
6550 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6552
6553 auto LibLoader = [](const std::string& LibName) -> bool {
6554 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6555 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6556 "Failed to load library %s", LibName.c_str());
6557 return false;
6558 }
6559 return true; //success.
6560 };
6561
6562 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6563 /*searchSystem=*/ true);
6564
6565 assert(!llvm::StringRef(libName).startswith("libNew") &&
6566 "We must not resolve symbols from libNew!");
6567
6568 if (libName.empty())
6569 return nullptr;
6570
6571 if (!LibLoader(libName))
6572 return nullptr;
6573
6574 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6575}
6576
6577////////////////////////////////////////////////////////////////////////////////
6578
6579Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6580{
6581 return fNSFromRootmaps.count(nsDecl) != 0;
6582}
6583
6584////////////////////////////////////////////////////////////////////////////////
6585/// Internal function. Actually do the update of the ClassInfo when seeing
6586// new TagDecl or NamespaceDecl.
6587void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6588{
6589
6591 if (cci) {
6592 // If we only had a forward declaration then update the
6593 // TClingClassInfo with the definition if we have it now.
6594 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6595 if (!oldDef || (def && def != oldDef)) {
6596 cl->ResetCaches();
6598 if (def) {
6599 // It's a tag decl, not a namespace decl.
6600 cci->Init(*cci->GetType());
6602 }
6603 }
6604 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6605 cl->ResetCaches();
6606 // yes, this is almost a waste of time, but we do need to lookup
6607 // the 'type' corresponding to the TClass anyway in order to
6608 // preserve the opaque typedefs (Double32_t)
6609 if (!alias && def != nullptr)
6610 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6611 else
6612 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6613 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6614 // We now need to update the state and bits.
6615 if (cl->fState != TClass::kHasTClassInit) {
6616 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6619 }
6620 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6621 } else {
6622 delete ((TClingClassInfo *)cl->fClassInfo);
6623 cl->fClassInfo = nullptr;
6624 }
6625 }
6626}
6627
6628////////////////////////////////////////////////////////////////////////////////
6629/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6630void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6631{
6632 const TagDecl *td = dyn_cast<TagDecl>(ND);
6633 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6634 const NamedDecl *canon = nullptr;
6635
6636 std::string name;
6637 TagDecl* tdDef = nullptr;
6638 if (td) {
6639 canon = tdDef = td->getDefinition();
6640 // Let's pass the decl to the TClass only if it has a definition.
6641 if (!tdDef) return;
6642
6643 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6644 // Ignore incomplete definition.
6645 // Ignore declaration within a function.
6646 return;
6647 }
6648
6649 auto declName = tdDef->getNameAsString();
6650 // Check if we have registered the unqualified name into the list
6651 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6652 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6653 // the unqualified name is sufficient (and the fully qualified name might be
6654 // 'wrong' if there is difference in spelling in the template paramters (for example)
6655 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6656 // 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() );
6657 return;
6658 }
6659
6660 clang::QualType type(tdDef->getTypeForDecl(), 0);
6662 } else if (ns) {
6663 canon = ns->getCanonicalDecl();
6664 name = ND->getQualifiedNameAsString();
6665 } else {
6666 name = ND->getQualifiedNameAsString();
6667 }
6668
6669 // Supposedly we are being called while something is being
6670 // loaded ... let's now tell the autoloader to do the work
6671 // yet another time.
6672 SuspendAutoLoadingRAII autoLoadOff(this);
6673 // FIXME: There can be more than one TClass for a single decl.
6674 // for example vector<double> and vector<Double32_t>
6675 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6676 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6677 RefreshClassInfo(cl, canon, false);
6678 }
6679 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6680 // and update them too:
6681 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6682 // RefreshClassInfo(cl, tdDef, true);
6683}
6684
6685////////////////////////////////////////////////////////////////////////////////
6686/// No op: see TClingCallbacks
6687
6688void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6689{
6690}
6691
6692//______________________________________________________________________________
6693//FIXME: Factor out that function in TClass, because TClass does it already twice
6694void TCling::UpdateClassInfoWork(const char* item)
6695{
6696 // This is a no-op as part of the API.
6697 // TCling uses UpdateClassInfoWithDecl() instead.
6698}
6699
6700////////////////////////////////////////////////////////////////////////////////
6701/// Update all canvases at end the terminal input command.
6702
6704{
6705 TIter next(gROOT->GetListOfCanvases());
6706 TVirtualPad* canvas;
6707 while ((canvas = (TVirtualPad*)next())) {
6708 canvas->Update();
6709 }
6710}
6711
6712////////////////////////////////////////////////////////////////////////////////
6713
6714void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6715 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6716
6717 // If the transaction does not contain anything we can return earlier.
6718 if (!HandleNewTransaction(T)) return;
6719
6720 bool isTUTransaction = false;
6721 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6722 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6723 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6724 // The is the first transaction, we have to expose to meta
6725 // what's already in the AST.
6726 isTUTransaction = true;
6727 }
6728 }
6729
6730 std::set<const void*> TransactionDeclSet;
6731 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6732 const clang::Decl* WrapperFD = T.getWrapperFD();
6733 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6734 I != E; ++I) {
6735 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6736 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6737 continue;
6738
6739 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6740 DE = I->m_DGR.end(); DI != DE; ++DI) {
6741 if (*DI == WrapperFD)
6742 continue;
6743 TransactionDeclSet.insert(*DI);
6744 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6745 }
6746 }
6747 }
6748
6749 // The above might trigger more decls to be deserialized.
6750 // Thus the iteration over the deserialized decls must be last.
6751 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6752 E = T.deserialized_decls_end(); I != E; ++I) {
6753 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6754 DE = I->m_DGR.end(); DI != DE; ++DI)
6755 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6756 //FIXME: HandleNewDecl should take DeclGroupRef
6757 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6758 modifiedTClasses);
6759 }
6760 }
6761
6762
6763 // When fully building the reflection info in TClass, a deserialization
6764 // could be triggered, which may result in request for building the
6765 // reflection info for the same TClass. This in turn will clear the caches
6766 // for the TClass in-flight and cause null ptr derefs.
6767 // FIXME: This is a quick fix, solving most of the issues. The actual
6768 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6769 // itself until the update is done.
6770 //
6771 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6772 std::vector<TClass*>::iterator it;
6773 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6774 ((TCling*)gCling)->GetModTClasses().begin(),
6775 ((TCling*)gCling)->GetModTClasses().end(),
6776 modifiedTClassesDiff.begin());
6777 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6778
6779 // Lock the TClass for updates
6780 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6781 modifiedTClassesDiff.end());
6782 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6783 E = modifiedTClassesDiff.end(); I != E; ++I) {
6784 // Make sure the TClass has not been deleted.
6785 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6786 continue;
6787 }
6788 // Could trigger deserialization of decls.
6789 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6790 // Unlock the TClass for updates
6791 ((TCling*)gCling)->GetModTClasses().erase(*I);
6792
6793 }
6794}
6795
6796///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6797///
6798void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6799{
6801
6802 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6803 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6804 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6805 (TListOfEnums *)gROOT->GetListOfEnums());
6806
6807 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6808 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6809 I != E; ++I) {
6810 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6811 continue;
6812 if (I->m_Call == cling::Transaction::kCCINone) {
6813 UpdateListsOnUnloaded(*(*iNested));
6814 ++iNested;
6815 continue;
6816 }
6817
6818 for (auto &D : I->m_DGR)
6819 InvalidateCachedDecl(Lists, D);
6820 }
6821}
6822
6823///\brief Invalidate cached TCling information for the given global declaration.
6824///
6825void TCling::InvalidateGlobal(const Decl *D) {
6826 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6827 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6828 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6829 (TListOfEnums *)gROOT->GetListOfEnums());
6830 InvalidateCachedDecl(Lists, D);
6831}
6832
6833///\brief Invalidate cached TCling information for the given declaration, and
6834/// removed it from the appropriate object list.
6835///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6836/// TListOfFunctionTemplates&, TListOfEnums&>
6837/// of pointers to the (global/class) object lists.
6838///\param[in] D - Decl to discard.
6839///
6843 TListOfEnums*> &Lists, const Decl *D) {
6844 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6845 return;
6846
6847 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6848 TListOfFunctions &LOF = *(std::get<1>(Lists));
6849 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6850 TListOfEnums &LOE = *(std::get<3>(Lists));
6851
6852 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6853 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6854 if (LODM.GetClass())
6855 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6856 else
6857 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6858 } else if (isa<FunctionDecl>(D)) {
6860 } else if (isa<FunctionTemplateDecl>(D)) {
6862 } else if (isa<EnumDecl>(D)) {
6863 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6864 if (!E)
6865 return;
6866
6867 // Try to invalidate enumerators (for unscoped enumerations).
6868 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6870 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6871
6873 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6874 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6875 return;
6876
6877 std::vector<TClass *> Classes;
6878 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6879 return;
6880 for (auto &C : Classes) {
6881 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6882 (TListOfFunctions *)C->GetListOfMethods(),
6883 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6884 (TListOfEnums *)C->GetListOfEnums());
6885 for (auto &I : cast<DeclContext>(D)->decls())
6886 InvalidateCachedDecl(Lists, I);
6887
6888 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6889 if (D->getKind() != Decl::Namespace
6890 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6891 C->ResetClassInfo();
6892 }
6893 }
6894}
6895
6896////////////////////////////////////////////////////////////////////////////////
6897// If an autoparse was done during a transaction and that it is rolled back,
6898// we need to make sure the next request for the same autoparse will be
6899// honored.
6900void TCling::TransactionRollback(const cling::Transaction &T) {
6901 auto const &triter = fTransactionHeadersMap.find(&T);
6902 if (triter != fTransactionHeadersMap.end()) {
6903 std::size_t normNameHash = triter->second;
6904
6905 fLookedUpClasses.erase(normNameHash);
6906
6907 auto const &iter = fClassesHeadersMap.find(normNameHash);
6908 if (iter != fClassesHeadersMap.end()) {
6909 auto const &hNamesPtrs = iter->second;
6910 for (auto &hName : hNamesPtrs) {
6911 if (gDebug > 0) {
6912 Info("TransactionRollback",
6913 "Restoring ability to autoaparse: %s", hName);
6914 }
6915 fParsedPayloadsAddresses.erase(hName);
6916 }
6917 }
6918 }
6919}
6920
6921////////////////////////////////////////////////////////////////////////////////
6922
6923void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6924// R__LOCKGUARD_CLING(gInterpreterMutex);
6925// UpdateListOfLoadedSharedLibraries();
6926}
6927
6928////////////////////////////////////////////////////////////////////////////////
6929
6930void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6931 fPrevLoadedDynLibInfo = nullptr;
6932 fSharedLibs = "";
6933}
6934
6935////////////////////////////////////////////////////////////////////////////////
6936/// Return the list of shared libraries loaded into the process.
6937
6939{
6942 return fSharedLibs;
6943}
6944
6945static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6946{
6947 if (!cls || !*cls)
6948 return {};
6949
6950 using namespace clang;
6951 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6952 /*type*/ nullptr, /*instantiate*/ false)) {
6953 if (!D->isFromASTFile()) {
6954 if (gDebug > 5)
6955 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6956 return {};
6957 }
6958 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6959 llvm::DenseSet<Module *> &m_TopLevelModules;
6960
6961 public:
6962 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6963 void Collect(const Decl *D) { Visit(D); }
6964
6965 void VisitDecl(const Decl *D)
6966 {
6967 // FIXME: Such case is described ROOT-7765 where
6968 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6969 // They are specified as #includes in the LinkDef file. This leads to
6970 // generation of incomplete modulemap files and this logic fails to
6971 // compute the corresponding module of D.
6972 // FIXME: If we want to support such a case, we should not rely on
6973 // the contents of the modulemap but mangle D and look it up in the
6974 // .so files.
6975 if (!D->hasOwningModule())
6976 return;
6977 if (Module *M = D->getOwningModule()->getTopLevelModule())
6978 m_TopLevelModules.insert(M);
6979 }
6980
6981 void VisitTemplateArgument(const TemplateArgument &TA)
6982 {
6983 switch (TA.getKind()) {
6984 case TemplateArgument::Null:
6985 case TemplateArgument::Integral:
6986 case TemplateArgument::Pack:
6987 case TemplateArgument::NullPtr:
6988 case TemplateArgument::Expression:
6989 case TemplateArgument::Template:
6990 case TemplateArgument::TemplateExpansion: return;
6991 case TemplateArgument::Type:
6992 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
6993 return Visit(TagTy->getDecl());
6994 return;
6995 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
6996 }
6997 llvm_unreachable("Invalid TemplateArgument::Kind!");
6998 }
6999
7000 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7001 {
7002 if (CTSD->getOwningModule())
7003 VisitDecl(CTSD);
7004 else
7005 VisitDecl(CTSD->getSpecializedTemplate());
7006 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7007 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7008 VisitTemplateArgument(*Arg);
7009 }
7010 }
7011 };
7012
7013 llvm::DenseSet<Module *> TopLevelModules;
7014 ModuleCollector m(TopLevelModules);
7015 m.Collect(D);
7016 std::string result;
7017 for (auto M : TopLevelModules) {
7018 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7019 // link declaration.
7020 if (!M->LinkLibraries.size())
7021 continue;
7022 // We have preloaded the Core module thus libCore.so
7023 if (M->Name == "Core")
7024 continue;
7025 assert(M->LinkLibraries.size() == 1);
7026 if (!result.empty())
7027 result += ' ';
7028 result += M->LinkLibraries[0].Library;
7029 }
7030 return result;
7031 }
7032 return {};
7033}
7034
7035////////////////////////////////////////////////////////////////////////////////
7036/// Get the list of shared libraries containing the code for class cls.
7037/// The first library in the list is the one containing the class, the
7038/// others are the libraries the first one depends on. Returns 0
7039/// in case the library is not found.
7040
7041const char* TCling::GetClassSharedLibs(const char* cls)
7042{
7043 if (fCxxModulesEnabled) {
7044 // Lock the interpreter mutex before interacting with cling.
7045 // TODO: Can we move this further deep? In principle the lock should be in
7046 // GetClassSharedLibsForModule, but it might be needed also for
7047 // getLookupHelper?
7049 llvm::StringRef className = cls;
7050 // If we get a class name containing lambda, we cannot parse it and we
7051 // can exit early.
7052 // FIXME: This works around a bug when we are instantiating a template
7053 // make_unique and the substitution fails. Seen in most of the dataframe
7054 // tests.
7055 if (className.contains("(lambda)"))
7056 return nullptr;
7057 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7058 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7059 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7060 std::string libs = GetClassSharedLibsForModule(cls, LH);
7061 if (!libs.empty()) {
7062 fAutoLoadLibStorage.push_back(libs);
7063 return fAutoLoadLibStorage.back().c_str();
7064 }
7065 }
7066
7067 if (!cls || !*cls) {
7068 return nullptr;
7069 }
7070 // lookup class to find list of libraries
7071 if (fMapfile) {
7072 TEnvRec* libs_record = nullptr;
7073 libs_record = fMapfile->Lookup(cls);
7074 if (libs_record) {
7075 const char* libs = libs_record->GetValue();
7076 return (*libs) ? libs : nullptr;
7077 }
7078 else {
7079 // Try the old format...
7080 TString c = TString("Library.") + cls;
7081 // convert "::" to "@@", we used "@@" because TEnv
7082 // considers "::" a terminator
7083 c.ReplaceAll("::", "@@");
7084 // convert "-" to " ", since class names may have
7085 // blanks and TEnv considers a blank a terminator
7086 c.ReplaceAll(" ", "-");
7087 // Use TEnv::Lookup here as the rootmap file must start with Library.
7088 // and do not support using any stars (so we do not need to waste time
7089 // with the search made by TEnv::GetValue).
7090 TEnvRec* libs_record = nullptr;
7091 libs_record = fMapfile->Lookup(c);
7092 if (libs_record) {
7093 const char* libs = libs_record->GetValue();
7094 return (*libs) ? libs : nullptr;
7095 }
7096 }
7097 }
7098 return nullptr;
7099}
7100
7101/// This interface returns a list of dependent libraries in the form:
7102/// lib libA.so libB.so libC.so. The first library is the library we are
7103/// searching dependencies for.
7104/// Note: In order to speed up the search, we display the dependencies of the
7105/// libraries which are not yet loaded. For instance, if libB.so was already
7106/// loaded the list would contain: lib libA.so libC.so.
7107static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7108 cling::Interpreter *interp,
7109 bool skipLoadedLibs = true)
7110{
7111 TString LibFullPath(lib);
7112 if (!llvm::sys::path::is_absolute(lib)) {
7113 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7114 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7115 return "";
7116 }
7117 } else {
7118 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7119 lib = llvm::sys::path::filename(lib).str();
7120 }
7121
7122 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7123 if (!ObjF) {
7124 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7125 return "";
7126 }
7127
7128 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7129
7130 std::set<string> DedupSet;
7131 std::string Result = lib + ' ';
7132 for (const auto &S : BinObjFile->symbols()) {
7133 uint32_t Flags = llvm::cantFail(S.getFlags());
7134 // Skip defined symbols: we have them.
7135 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7136 continue;
7137 // Skip undefined weak symbols: if we don't have them we won't need them.
7138 // `__gmon_start__` being a typical example.
7139 if (Flags & llvm::object::SymbolRef::SF_Weak)
7140 continue;
7141 llvm::Expected<StringRef> SymNameErr = S.getName();
7142 if (!SymNameErr) {
7143 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7144 continue;
7145 }
7146 llvm::StringRef SymName = SymNameErr.get();
7147 if (SymName.empty())
7148 continue;
7149
7150 if (BinObjFile->isELF()) {
7151 // Skip the symbols which are part of the C/C++ runtime and have a
7152 // fixed library version. See binutils ld VERSION. Those reside in
7153 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7154 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7155 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7156 continue;
7157
7158 // Those are 'weak undefined' symbols produced by gcc. We can
7159 // ignore them.
7160 // FIXME: It is unclear whether we can ignore all weak undefined
7161 // symbols:
7162 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7163 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7164 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7165 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7166 if (SymName == RegisterClasses ||
7167 SymName == RegisterCloneTable ||
7168 SymName == DeregisterCloneTable)
7169 continue;
7170 }
7171
7172 // If we can find the address of the symbol, we have loaded it. Skip.
7173 if (skipLoadedLibs) {
7174 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7175 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7176 continue;
7177 }
7178
7180 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7181 // The expected output is just filename without the full path, which
7182 // is not very accurate, because our Dyld implementation might find
7183 // a match in location a/b/c.so and if we return just c.so ROOT might
7184 // resolve it to y/z/c.so and there we might not be ABI compatible.
7185 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7186 if (!found.empty()) {
7187 std::string cand = llvm::sys::path::filename(found).str();
7188 if (!DedupSet.insert(cand).second)
7189 continue;
7190
7191 Result += cand + ' ';
7192 }
7193 }
7194
7195 return Result;
7196}
7197
7198static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7199{
7200 // Check if we have parsed a rootmap file.
7201 llvm::SmallString<256> rootmapName;
7202 if (!lib.startswith("lib"))
7203 rootmapName.append("lib");
7204
7205 rootmapName.append(llvm::sys::path::filename(lib));
7206 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7207
7208 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7209 return true;
7210
7211 // Perform a last resort by dropping the lib prefix.
7212 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7213 if (rootmapNameNoLib.consume_front("lib"))
7214 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7215
7216 return false;
7217}
7218
7219static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7220{
7221 if (gCling->HasPCMForLibrary(lib.data()))
7222 return true;
7223
7224 return hasParsedRootmapForLibrary(lib);
7225}
7226
7227////////////////////////////////////////////////////////////////////////////////
7228/// Get the list a libraries on which the specified lib depends. The
7229/// returned string contains as first element the lib itself.
7230/// Returns 0 in case the lib does not exist or does not have
7231/// any dependencies. If useDyld is true, we iterate through all available
7232/// libraries and try to construct the dependency chain by resolving each
7233/// symbol.
7234
7235const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7236{
7237 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7238 return nullptr;
7239
7240 if (!hasParsedRootmapForLibrary(lib)) {
7241 llvm::SmallString<512> rootmapName(lib);
7242 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7243 if (llvm::sys::fs::exists(rootmapName)) {
7244 if (gDebug > 0)
7245 Info("Load", "loading %s", rootmapName.c_str());
7246 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7247 }
7248 }
7249
7250 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7251 if (gDebug > 0)
7252 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7253 }
7254
7255 if (useDyld) {
7256 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7257 if (!libs.empty()) {
7258 fAutoLoadLibStorage.push_back(libs);
7259 return fAutoLoadLibStorage.back().c_str();
7260 }
7261 }
7262
7263 if (!fMapfile || !lib || !lib[0]) {
7264 return nullptr;
7265 }
7266 TString libname(lib);
7267 Ssiz_t idx = libname.Last('.');
7268 if (idx != kNPOS) {
7269 libname.Remove(idx);
7270 }
7271 TEnvRec* rec;
7272 TIter next(fMapfile->GetTable());
7273 size_t len = libname.Length();
7274 while ((rec = (TEnvRec*) next())) {
7275 const char* libs = rec->GetValue();
7276 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7277 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7278 return libs;
7279 }
7280 }
7281 return nullptr;
7282}
7283
7284////////////////////////////////////////////////////////////////////////////////
7285/// If error messages are disabled, the interpreter should suppress its
7286/// failures and warning messages from stdout.
7287
7289{
7290#if defined(R__MUST_REVISIT)
7291#if R__MUST_REVISIT(6,2)
7292 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7293#endif
7294#endif
7295 return kTRUE;
7296}
7297
7298////////////////////////////////////////////////////////////////////////////////
7299/// If error messages are disabled, the interpreter should suppress its
7300/// failures and warning messages from stdout. Return the previous state.
7301
7303{
7304#if defined(R__MUST_REVISIT)
7305#if R__MUST_REVISIT(6,2)
7306 Warning("SetErrorMessages", "Interface not available yet.");
7307#endif
7308#endif
7310}
7311
7312////////////////////////////////////////////////////////////////////////////////
7313/// Refresh the list of include paths known to the interpreter and return it
7314/// with -I prepended.
7315
7317{
7319
7320 fIncludePath = "";
7321
7322 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7323 //false - no system header, true - with flags.
7324 fInterpreter->GetIncludePaths(includePaths, false, true);
7325 if (const size_t nPaths = includePaths.size()) {
7326 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7327
7328 for (size_t i = 0; i < nPaths; i += 2) {
7329 if (i)
7330 fIncludePath.Append(' ');
7331 fIncludePath.Append(includePaths[i].c_str());
7332
7333 if (includePaths[i] != "-I")
7334 fIncludePath.Append(' ');
7335 fIncludePath.Append('"');
7336 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7337 fIncludePath.Append('"');
7338 }
7339 }
7340
7341 return fIncludePath;
7342}
7343
7344////////////////////////////////////////////////////////////////////////////////
7345/// Return the directory containing CINT's stl cintdlls.
7346
7347const char* TCling::GetSTLIncludePath() const
7348{
7349 return "";
7350}
7351
7352//______________________________________________________________________________
7353// M I S C
7354//______________________________________________________________________________
7355
7356int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7357{
7358 // Interface to cling function
7359 return 0;
7360}
7361
7362////////////////////////////////////////////////////////////////////////////////
7363/// Interface to cling function
7364
7365int TCling::DisplayIncludePath(FILE *fout) const
7366{
7367 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7368
7369 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7370 //false - no system header, true - with flags.
7371 fInterpreter->GetIncludePaths(includePaths, false, true);
7372 if (const size_t nPaths = includePaths.size()) {
7373 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7374
7375 std::string allIncludes("include path:");
7376 for (size_t i = 0; i < nPaths; i += 2) {
7377 allIncludes += ' ';
7378 allIncludes += includePaths[i];
7379
7380 if (includePaths[i] != "-I")
7381 allIncludes += ' ';
7382 allIncludes += includePaths[i + 1];
7383 }
7384
7385 fprintf(fout, "%s\n", allIncludes.c_str());
7386 }
7387
7388 return 0;
7389}
7390
7391////////////////////////////////////////////////////////////////////////////////
7392/// Interface to cling function
7393
7394void* TCling::FindSym(const char* entry) const
7395{
7396 return fInterpreter->getAddressOfGlobal(entry);
7397}
7398
7399////////////////////////////////////////////////////////////////////////////////
7400/// Let the interpreter issue a generic error, and set its error state.
7401
7402void TCling::GenericError(const char* error) const
7403{
7404#if defined(R__MUST_REVISIT)
7405#if R__MUST_REVISIT(6,2)
7406 Warning("GenericError","Interface not available yet.");
7407#endif
7408#endif
7409}
7410
7411////////////////////////////////////////////////////////////////////////////////
7412/// This routines used to return the address of the internal wrapper
7413/// function (of the interpreter) that was used to call *all* the
7414/// interpreted functions that were bytecode compiled (no longer
7415/// interpreted line by line). In Cling, there is no such
7416/// wrapper function.
7417/// In practice this routines was use to decipher whether the
7418/// pointer returns by InterfaceMethod could be used to uniquely
7419/// represent the function. In Cling if the function is in a
7420/// useable state (its compiled version is available), this is
7421/// always the case.
7422/// See TClass::GetMethod.
7423
7425{
7426 return 0;
7427}
7428
7429////////////////////////////////////////////////////////////////////////////////
7430/// Interface to cling function
7431
7433{
7434#if defined(R__MUST_REVISIT)
7435#if R__MUST_REVISIT(6,2)
7436 Warning("GetSecurityError", "Interface not available yet.");
7437#endif
7438#endif
7439 return 0;
7440}
7441
7442////////////////////////////////////////////////////////////////////////////////
7443/// Load a source file or library called path into the interpreter.
7444
7445int TCling::LoadFile(const char* path) const
7446{
7447 // Modifying the interpreter state needs locking.
7449 cling::Interpreter::CompilationResult compRes;
7450 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7451 return compRes == cling::Interpreter::kFailure;
7452}
7453
7454////////////////////////////////////////////////////////////////////////////////
7455/// Load the declarations from text into the interpreter.
7456/// Note that this cannot be (top level) statements; text must contain
7457/// top level declarations.
7458/// Returns true on success, false on failure.
7459
7460Bool_t TCling::LoadText(const char* text) const
7461{
7462 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7463}
7464
7465////////////////////////////////////////////////////////////////////////////////
7466/// Interface to cling function
7467
7468const char* TCling::MapCppName(const char* name) const
7469{
7470 TTHREAD_TLS_DECL(std::string,buffer);
7472 return buffer.c_str(); // NOLINT
7473}
7474
7475////////////////////////////////////////////////////////////////////////////////
7476/// [Place holder for Mutex Lock]
7477/// Provide the interpreter with a way to
7478/// acquire a lock used to protect critical section
7479/// of its code (non-thread safe parts).
7480
7481void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7482{
7483 // nothing to do for now.
7484}
7485
7486////////////////////////////////////////////////////////////////////////////////
7487/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7488/// release a lock used to protect critical section
7489/// of its code (non-thread safe parts).
7490
7491void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7492{
7493 // nothing to do for now.
7494}
7495
7496////////////////////////////////////////////////////////////////////////////////
7497/// Returns if class AutoLoading is currently enabled.
7498
7500{
7501 if (IsFromRootCling())
7502 return false;
7503 if (!fClingCallbacks)
7504 return false;
7506}
7507
7508////////////////////////////////////////////////////////////////////////////////
7509/// Enable/Disable the AutoLoading of libraries.
7510/// Returns the old value, i.e whether it was enabled or not.
7511
7512int TCling::SetClassAutoLoading(int autoload) const
7513{
7514 // If no state change is required, exit early.
7515 // FIXME: In future we probably want to complain if we made a request which
7516 // was with the same state as before in order to catch programming errors.
7517 if ((bool) autoload == IsClassAutoLoadingEnabled())
7518 return autoload;
7519
7520 assert(fClingCallbacks && "We must have callbacks!");
7521 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7523 return oldVal;
7524}
7525
7526////////////////////////////////////////////////////////////////////////////////
7527/// Enable/Disable the Autoparsing of headers.
7528/// Returns the old value, i.e whether it was enabled or not.
7529
7531{
7532 bool oldVal = fHeaderParsingOnDemand;
7533 fHeaderParsingOnDemand = autoparse;
7534 return oldVal;
7535}
7536
7537////////////////////////////////////////////////////////////////////////////////
7538/// Suspend the Autoparsing of headers.
7539/// Returns the old value, i.e whether it was suspended or not.
7540
7545 return old;
7546}
7547
7548////////////////////////////////////////////////////////////////////////////////
7549/// Set a callback to receive error messages.
7550
7552{
7553#if defined(R__MUST_REVISIT)
7554#if R__MUST_REVISIT(6,2)
7555 Warning("SetErrmsgcallback", "Interface not available yet.");
7556#endif
7557#endif
7558}
7559
7561{
7562 if (enable) {
7563 auto consumer = new TClingDelegateDiagnosticPrinter(
7564 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7565 fInterpreter->getCI()->getLangOpts(),
7566 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7567 if (Level == clang::DiagnosticsEngine::Warning) {
7568 ::Warning("cling", "%s", Info.c_str());
7569 } else if (Level == clang::DiagnosticsEngine::Error
7570 || Level == clang::DiagnosticsEngine::Fatal) {
7571 ::Error("cling", "%s", Info.c_str());
7572 } else {
7573 ::Info("cling", "%s", Info.c_str());
7574 }
7575 });
7576 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7577 } else {
7578 fInterpreter->replaceDiagnosticConsumer(nullptr);
7579 }
7580}
7581
7582
7583////////////////////////////////////////////////////////////////////////////////
7584/// Create / close a scope for temporaries. No-op for cling; use
7585/// cling::Value instead.
7586
7587void TCling::SetTempLevel(int val) const
7588{
7589}
7590
7591////////////////////////////////////////////////////////////////////////////////
7592
7593int TCling::UnloadFile(const char* path) const
7594{
7595 // Modifying the interpreter state needs locking.
7597 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7598 std::string canonical = DLM->lookupLibrary(path);
7599 if (canonical.empty()) {
7600 canonical = path;
7601 }
7602 // Unload a shared library or a source file.
7603 cling::Interpreter::CompilationResult compRes;
7604 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7605 return compRes == cling::Interpreter::kFailure;
7606}
7607
7608std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7609 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7610}
7611
7612////////////////////////////////////////////////////////////////////////////////
7613/// The call to Cling's tab complition.
7614
7615void TCling::CodeComplete(const std::string& line, size_t& cursor,
7616 std::vector<std::string>& completions)
7617{
7618 fInterpreter->codeComplete(line, cursor, completions);
7619}
7620
7621////////////////////////////////////////////////////////////////////////////////
7622/// Get the interpreter value corresponding to the statement.
7624{
7625 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7626 auto compRes = fInterpreter->evaluate(code, *V);
7627 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7628}
7629
7630////////////////////////////////////////////////////////////////////////////////
7631
7633{
7634 using namespace cling;
7635 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7637}
7638
7639////////////////////////////////////////////////////////////////////////////////
7640/// Register value as a temporary, extending its lifetime to that of the
7641/// interpreter. This is needed for TCling's compatibility interfaces
7642/// returning long - the address of the temporary objects.
7643/// As such, "simple" types don't need to be stored; they are returned by
7644/// value; only pointers / references / objects need to be stored.
7645
7646void TCling::RegisterTemporary(const cling::Value& value)
7647{
7648 if (value.isValid() && value.needsManagedAllocation()) {
7650 fTemporaries->push_back(value);
7651 }
7652}
7653
7654////////////////////////////////////////////////////////////////////////////////
7655/// If the interpreter encounters Name, check whether that is an object ROOT
7656/// could retrieve. To not re-read objects from disk, cache the name/object
7657/// pair for a given LookupCtx.
7658
7659TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7660{
7661 // The call to FindSpecialObject might induces any kind of use
7662 // of the interpreter ... (library loading, function calling, etc.)
7663 // ... and we _know_ we are in the middle of parsing, so let's make
7664 // sure to save the state and then restore it.
7665
7666 if (gDirectory) {
7667 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7668 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7669 auto iSpecObj = iSpecObjMap->second.find(Name);
7670 if (iSpecObj != iSpecObjMap->second.end()) {
7671 LookupCtx = gDirectory;
7672 return iSpecObj->second;
7673 }
7674 }
7675 }
7676
7677 // Save state of the PP
7678 Sema &SemaR = fInterpreter->getSema();
7679 ASTContext& C = SemaR.getASTContext();
7680 Preprocessor &PP = SemaR.getPreprocessor();
7681 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7682 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7683 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7684 // After we have saved the token reset the current one to something which
7685 // is safe (semi colon usually means empty decl)
7686 Token& Tok = const_cast<Token&>(P.getCurToken());
7687 Tok.setKind(tok::semi);
7688
7689 // We can't PushDeclContext, because we go up and the routine that pops
7690 // the DeclContext assumes that we drill down always.
7691 // We have to be on the global context. At that point we are in a
7692 // wrapper function so the parent context must be the global.
7693 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7694 SemaR.TUScope);
7695
7696 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7697 if (specObj) {
7698 if (!LookupCtx) {
7699 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7700 } else {
7701 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7702 }
7703 }
7704 return specObj;
7705}
7706
7707////////////////////////////////////////////////////////////////////////////////
7708/// Inject function as a friend into klass.
7709/// With function being f in void f() {new N::PrivKlass(); } this enables
7710/// I/O of non-public classes.
7711
7712void TCling::AddFriendToClass(clang::FunctionDecl* function,
7713 clang::CXXRecordDecl* klass) const
7714{
7715 using namespace clang;
7716 ASTContext& Ctx = klass->getASTContext();
7717 FriendDecl::FriendUnion friendUnion(function);
7718 // one dummy object for the source location
7719 SourceLocation sl;
7720 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7721 klass->pushFriendDecl(friendDecl);
7722}
7723
7724//______________________________________________________________________________
7725//
7726// DeclId getter.
7727//
7728
7729////////////////////////////////////////////////////////////////////////////////
7730/// Return a unique identifier of the declaration represented by the
7731/// CallFunc
7732
7734{
7735 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7736 return nullptr;
7737}
7738
7739////////////////////////////////////////////////////////////////////////////////
7740/// Return a (almost) unique identifier of the declaration represented by the
7741/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7742/// when the underlying class is a template instance involving one of the
7743/// opaque typedef.
7744
7746{
7747 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7748 return nullptr;
7749}
7750
7751////////////////////////////////////////////////////////////////////////////////
7752/// Return a unique identifier of the declaration represented by the
7753/// MethodInfo
7754
7756{
7757 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7758 return nullptr;
7759}
7760
7761////////////////////////////////////////////////////////////////////////////////
7762/// Return a unique identifier of the declaration represented by the
7763/// MethodInfo
7764
7766{
7767 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7768 return nullptr;
7769}
7770
7771////////////////////////////////////////////////////////////////////////////////
7772/// Return a unique identifier of the declaration represented by the
7773/// TypedefInfo
7774
7776{
7777 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7778 return nullptr;
7779}
7780
7781//______________________________________________________________________________
7782//
7783// CallFunc interface
7784//
7785
7786////////////////////////////////////////////////////////////////////////////////
7787
7788void TCling::CallFunc_Delete(CallFunc_t* func) const
7789{
7790 delete (TClingCallFunc*) func;
7791}
7792
7793////////////////////////////////////////////////////////////////////////////////
7794
7795void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7796{
7797 TClingCallFunc* f = (TClingCallFunc*) func;
7798 f->Exec(address);
7799}
7800
7801////////////////////////////////////////////////////////////////////////////////
7802
7803void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7804{
7805 TClingCallFunc* f = (TClingCallFunc*) func;
7806 f->Exec(address, &val);
7807}
7808
7809////////////////////////////////////////////////////////////////////////////////
7810
7811void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7812{
7813 TClingCallFunc* f = (TClingCallFunc*) func;
7814 f->ExecWithReturn(address, ret);
7815}
7816
7817////////////////////////////////////////////////////////////////////////////////
7818
7819void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7820 const void* args[] /*=0*/,
7821 int nargs /*=0*/,
7822 void* ret/*=0*/) const
7823{
7824 TClingCallFunc* f = (TClingCallFunc*) func;
7825 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7826}
7827
7828////////////////////////////////////////////////////////////////////////////////
7829
7830Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7831{
7832 TClingCallFunc* f = (TClingCallFunc*) func;
7833 return f->ExecInt(address);
7834}
7835
7836////////////////////////////////////////////////////////////////////////////////
7837
7838Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7839{
7840 TClingCallFunc* f = (TClingCallFunc*) func;
7841 return f->ExecInt64(address);
7842}
7843
7844////////////////////////////////////////////////////////////////////////////////
7845
7846Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7847{
7848 TClingCallFunc* f = (TClingCallFunc*) func;
7849 return f->ExecDouble(address);
7850}
7851
7852////////////////////////////////////////////////////////////////////////////////
7853
7854CallFunc_t* TCling::CallFunc_Factory() const
7855{
7857 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7858}
7859
7860////////////////////////////////////////////////////////////////////////////////
7861
7862CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7863{
7864 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7865}
7866
7867////////////////////////////////////////////////////////////////////////////////
7868
7869MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7870{
7871 TClingCallFunc* f = (TClingCallFunc*) func;
7872 return (MethodInfo_t*) f->FactoryMethod();
7873}
7874
7875////////////////////////////////////////////////////////////////////////////////
7876
7877void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7878{
7879 TClingCallFunc* f = (TClingCallFunc*) func;
7880 f->IgnoreExtraArgs(ignore);
7881}
7882
7883////////////////////////////////////////////////////////////////////////////////
7884
7885void TCling::CallFunc_Init(CallFunc_t* func) const
7886{
7888 TClingCallFunc* f = (TClingCallFunc*) func;
7889 f->Init();
7890}
7891
7892////////////////////////////////////////////////////////////////////////////////
7893
7894bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7895{
7896 TClingCallFunc* f = (TClingCallFunc*) func;
7897 return f->IsValid();
7898}
7899
7900////////////////////////////////////////////////////////////////////////////////
7901
7903TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7904{
7905 TClingCallFunc* f = (TClingCallFunc*) func;
7906 return f->IFacePtr();
7907}
7908
7909////////////////////////////////////////////////////////////////////////////////
7910
7911void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7912{
7913 TClingCallFunc* f = (TClingCallFunc*) func;
7914 f->ResetArg();
7915}
7916
7917////////////////////////////////////////////////////////////////////////////////
7918
7919void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7920{
7921 TClingCallFunc* f = (TClingCallFunc*) func;
7922 f->SetArg(param);
7923}
7924
7925////////////////////////////////////////////////////////////////////////////////
7926
7927void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7928{
7929 TClingCallFunc* f = (TClingCallFunc*) func;
7930 f->SetArg(param);
7931}
7932
7933////////////////////////////////////////////////////////////////////////////////
7934
7935void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7936{
7937 TClingCallFunc* f = (TClingCallFunc*) func;
7938 f->SetArg(param);
7939}
7940
7941////////////////////////////////////////////////////////////////////////////////
7942
7943void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7944{
7945 TClingCallFunc* f = (TClingCallFunc*) func;
7946 f->SetArg(param);
7947}
7948
7949////////////////////////////////////////////////////////////////////////////////
7950
7951void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7952{
7953 TClingCallFunc* f = (TClingCallFunc*) func;
7954 f->SetArg(param);
7955}
7956
7957////////////////////////////////////////////////////////////////////////////////
7958
7959void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7960{
7961 TClingCallFunc* f = (TClingCallFunc*) func;
7962 f->SetArg(param);
7963}
7964
7965////////////////////////////////////////////////////////////////////////////////
7966
7967void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
7968{
7969 TClingCallFunc* f = (TClingCallFunc*) func;
7970 f->SetArgArray(paramArr, nparam);
7971}
7972
7973////////////////////////////////////////////////////////////////////////////////
7974
7975void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7976{
7977 TClingCallFunc* f = (TClingCallFunc*) func;
7978 f->SetArgs(param);
7979}
7980
7981////////////////////////////////////////////////////////////////////////////////
7982
7983void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
7984{
7985 TClingCallFunc* f = (TClingCallFunc*) func;
7986 TClingClassInfo* ci = (TClingClassInfo*) info;
7987 f->SetFunc(ci, method, params, offset);
7988}
7989
7990////////////////////////////////////////////////////////////////////////////////
7991
7992void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
7993{
7994 TClingCallFunc* f = (TClingCallFunc*) func;
7995 TClingClassInfo* ci = (TClingClassInfo*) info;
7996 f->SetFunc(ci, method, params, objectIsConst, offset);
7997}
7998////////////////////////////////////////////////////////////////////////////////
7999
8000void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8001{
8002 TClingCallFunc* f = (TClingCallFunc*) func;
8003 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8004 f->SetFunc(minfo);
8005}
8006
8007////////////////////////////////////////////////////////////////////////////////
8008/// Interface to cling function
8009
8010void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8011{
8012 TClingCallFunc* f = (TClingCallFunc*) func;
8013 TClingClassInfo* ci = (TClingClassInfo*) info;
8014 f->SetFuncProto(ci, method, proto, offset, mode);
8015}
8016
8017////////////////////////////////////////////////////////////////////////////////
8018/// Interface to cling function
8019
8020void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8021{
8022 TClingCallFunc* f = (TClingCallFunc*) func;
8023 TClingClassInfo* ci = (TClingClassInfo*) info;
8024 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8025}
8026
8027////////////////////////////////////////////////////////////////////////////////
8028/// Interface to cling function
8029
8030void 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
8031{
8032 TClingCallFunc* f = (TClingCallFunc*) func;
8033 TClingClassInfo* ci = (TClingClassInfo*) info;
8034 llvm::SmallVector<clang::QualType, 4> funcProto;
8035 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8036 iter != end; ++iter) {
8037 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8038 }
8039 f->SetFuncProto(ci, method, funcProto, offset, mode);
8040}
8041
8042////////////////////////////////////////////////////////////////////////////////
8043/// Interface to cling function
8044
8045void 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
8046{
8047 TClingCallFunc* f = (TClingCallFunc*) func;
8048 TClingClassInfo* ci = (TClingClassInfo*) info;
8049 llvm::SmallVector<clang::QualType, 4> funcProto;
8050 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8051 iter != end; ++iter) {
8052 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8053 }
8054 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8055}
8056
8057std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8058{
8059 TClingCallFunc *f = (TClingCallFunc *)func;
8060 std::string wrapper_name;
8061 std::string wrapper;
8062 f->get_wrapper_code(wrapper_name, wrapper);
8063 return wrapper;
8064}
8065
8066//______________________________________________________________________________
8067//
8068// ClassInfo interface
8069//
8070
8071////////////////////////////////////////////////////////////////////////////////
8072/// Return true if the entity pointed to by 'declid' is declared in
8073/// the context described by 'info'. If info is null, look into the
8074/// global scope (translation unit scope).
8075
8076Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8077{
8078 if (!declid)
8079 return kFALSE;
8080
8081 const clang::DeclContext *ctxt = nullptr;
8082 if (info) {
8083 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8084 } else {
8085 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8086 }
8087 if (!ctxt)
8088 return kFALSE;
8089
8090 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8091 if (!decl)
8092 return kFALSE;
8093
8094 const clang::DeclContext *declDC = decl->getDeclContext();
8095 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8096 while (true) {
8097 if (declDC->isTransparentContext()) {
8098 declDC = declDC->getParent();
8099 continue;
8100 }
8101 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8102 if (declRD->isAnonymousStructOrUnion()) {
8103 declDC = declRD->getParent();
8104 continue;
8105 }
8106 }
8107 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8108 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8109 declDC = declNS->getParent();
8110 continue;
8111 }
8112 }
8113 break;
8114 }
8115
8116 return declDC->Equals(ctxt);
8117}
8118
8119////////////////////////////////////////////////////////////////////////////////
8120
8122{
8123 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8124 return TClinginfo->ClassProperty();
8125}
8126
8127////////////////////////////////////////////////////////////////////////////////
8128
8129void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8130{
8131 delete (TClingClassInfo*) cinfo;
8132}
8133
8134////////////////////////////////////////////////////////////////////////////////
8135
8136void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8137{
8138 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8139 TClinginfo->Delete(arena,*fNormalizedCtxt);
8140}
8141
8142////////////////////////////////////////////////////////////////////////////////
8143
8144void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8145{
8146 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8147 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8148}
8149
8150////////////////////////////////////////////////////////////////////////////////
8151
8152void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8153{
8154 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8155 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8156}
8157
8158////////////////////////////////////////////////////////////////////////////////
8159
8160ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8161{
8163 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8164}
8165
8166////////////////////////////////////////////////////////////////////////////////
8167
8168ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8169{
8170 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8171}
8172
8173////////////////////////////////////////////////////////////////////////////////
8174
8175ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8176{
8178 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8179}
8180
8181ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8182{
8184 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8185}
8186
8187
8188////////////////////////////////////////////////////////////////////////////////
8189
8190int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8191{
8192 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8193 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8194}
8195
8196////////////////////////////////////////////////////////////////////////////////
8197
8198bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8199{
8200 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8202}
8203
8204////////////////////////////////////////////////////////////////////////////////
8205
8206bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8207{
8208 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8209 return TClinginfo->HasMethod(name);
8210}
8211
8212////////////////////////////////////////////////////////////////////////////////
8213
8214void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8215{
8217 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8218 TClinginfo->Init(name);
8219}
8220
8221////////////////////////////////////////////////////////////////////////////////
8222
8223void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8224{
8226 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8227 TClinginfo->Init(tagnum);
8228}
8229
8230////////////////////////////////////////////////////////////////////////////////
8231
8232bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8233{
8234 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8235 return TClinginfo->IsBase(name);
8236}
8237
8238////////////////////////////////////////////////////////////////////////////////
8239
8240bool TCling::ClassInfo_IsEnum(const char* name) const
8241{
8243}
8244
8245////////////////////////////////////////////////////////////////////////////////
8246
8248{
8249 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8250 return TClinginfo->IsScopedEnum();
8251}
8252
8253
8254////////////////////////////////////////////////////////////////////////////////
8255
8257{
8258 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8259 return TClinginfo->GetUnderlyingType();
8260}
8261
8262
8263////////////////////////////////////////////////////////////////////////////////
8264
8265bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8266{
8267 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8268 return TClinginfo->IsLoaded();
8269}
8270
8271////////////////////////////////////////////////////////////////////////////////
8272
8273bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8274{
8275 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8276 return TClinginfo->IsValid();
8277}
8278
8279////////////////////////////////////////////////////////////////////////////////
8280
8281bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8282{
8283 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8284 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8285}
8286
8287////////////////////////////////////////////////////////////////////////////////
8288
8289bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8290{
8291 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8292 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8293}
8294
8295////////////////////////////////////////////////////////////////////////////////
8296
8297int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8298{
8299 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8300 return TClinginfo->Next();
8301}
8302
8303////////////////////////////////////////////////////////////////////////////////
8304
8305void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8306{
8307 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8308 return TClinginfo->New(*fNormalizedCtxt);
8309}
8310
8311////////////////////////////////////////////////////////////////////////////////
8312
8313void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8314{
8315 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8316 return TClinginfo->New(n,*fNormalizedCtxt);
8317}
8318
8319////////////////////////////////////////////////////////////////////////////////
8320
8321void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8322{
8323 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8324 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8325}
8326
8327////////////////////////////////////////////////////////////////////////////////
8328
8329void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8330{
8331 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8332 return TClinginfo->New(arena,*fNormalizedCtxt);
8333}
8334
8335////////////////////////////////////////////////////////////////////////////////
8336
8337Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8338{
8339 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8340 return TClinginfo->Property();
8341}
8342
8343////////////////////////////////////////////////////////////////////////////////
8344
8345int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8346{
8347 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8348 return TClinginfo->Size();
8349}
8350
8351////////////////////////////////////////////////////////////////////////////////
8352
8353Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8354{
8355 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8356 return TClinginfo->Tagnum();
8357}
8358
8359////////////////////////////////////////////////////////////////////////////////
8360
8361const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8362{
8363 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8364 return TClinginfo->FileName();
8365}
8366
8367////////////////////////////////////////////////////////////////////////////////
8368
8369const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8370{
8371 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8372 TTHREAD_TLS_DECL(std::string,output);
8373 TClinginfo->FullName(output,*fNormalizedCtxt);
8374 return output.c_str(); // NOLINT
8375}
8376
8377////////////////////////////////////////////////////////////////////////////////
8378
8379const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8380{
8381 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8382 return TClinginfo->Name();
8383}
8384
8385////////////////////////////////////////////////////////////////////////////////
8386
8387const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8388{
8389 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8390 return TClinginfo->Title();
8391}
8392
8393////////////////////////////////////////////////////////////////////////////////
8394
8395const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8396{
8397 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8398 return TClinginfo->TmpltName();
8399}
8400
8401
8402
8403//______________________________________________________________________________
8404//
8405// BaseClassInfo interface
8406//
8407
8408////////////////////////////////////////////////////////////////////////////////
8409
8410void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8411{
8412 delete(TClingBaseClassInfo*) bcinfo;
8413}
8414
8415////////////////////////////////////////////////////////////////////////////////
8416
8417BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8418{
8420 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8421 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8422}
8423
8424////////////////////////////////////////////////////////////////////////////////
8425
8426BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8427 ClassInfo_t* base) const
8428{
8430 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8431 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8432 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8433}
8434
8435////////////////////////////////////////////////////////////////////////////////
8436
8437int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8438{
8439 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8440 return TClinginfo->Next();
8441}
8442
8443////////////////////////////////////////////////////////////////////////////////
8444
8445int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8446{
8447 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8448 return TClinginfo->Next(onlyDirect);
8449}
8450
8451////////////////////////////////////////////////////////////////////////////////
8452
8453Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8454{
8455 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8456 return TClinginfo->Offset(address, isDerivedObject);
8457}
8458
8459////////////////////////////////////////////////////////////////////////////////
8460
8461Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8462{
8463 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8464 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8465 // Offset to the class itself.
8466 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8467 return 0;
8468 }
8469 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8470}
8471
8472////////////////////////////////////////////////////////////////////////////////
8473
8474Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8475{
8476 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8477 return TClinginfo->Property();
8478}
8479
8480////////////////////////////////////////////////////////////////////////////////
8481
8482ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8483{
8484 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8485 return (ClassInfo_t *)TClinginfo->GetBase();
8486}
8487
8488////////////////////////////////////////////////////////////////////////////////
8489
8490Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8491{
8492 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8493 return TClinginfo->Tagnum();
8494}
8495
8496////////////////////////////////////////////////////////////////////////////////
8497
8498const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8499{
8500 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8501 TTHREAD_TLS_DECL(std::string,output);
8502 TClinginfo->FullName(output,*fNormalizedCtxt);
8503 return output.c_str(); // NOLINT
8504}
8505
8506////////////////////////////////////////////////////////////////////////////////
8507
8508const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8509{
8510 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8511 return TClinginfo->Name();
8512}
8513
8514////////////////////////////////////////////////////////////////////////////////
8515
8516const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8517{
8518 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8519 return TClinginfo->TmpltName();
8520}
8521
8522//______________________________________________________________________________
8523//
8524// DataMemberInfo interface
8525//
8526
8527////////////////////////////////////////////////////////////////////////////////
8528
8529int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8530{
8531 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8532 return TClinginfo->ArrayDim();
8533}
8534
8535////////////////////////////////////////////////////////////////////////////////
8536
8537void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8538{
8539 delete(TClingDataMemberInfo*) dminfo;
8540}
8541
8542////////////////////////////////////////////////////////////////////////////////
8543
8544DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8545{
8547 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8548 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8549}
8550
8551////////////////////////////////////////////////////////////////////////////////
8552
8553DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8554{
8556 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8557 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8558 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8559}
8560
8561////////////////////////////////////////////////////////////////////////////////
8562
8563DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8564{
8565 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8566 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8567}
8568
8569////////////////////////////////////////////////////////////////////////////////
8570
8571bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8572{
8573 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8574 return TClinginfo->IsValid();
8575}
8576
8577////////////////////////////////////////////////////////////////////////////////
8578
8579int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8580{
8581 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8582 return TClinginfo->MaxIndex(dim);
8583}
8584
8585////////////////////////////////////////////////////////////////////////////////
8586
8587int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8588{
8589 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8590 return TClinginfo->Next();
8591}
8592
8593////////////////////////////////////////////////////////////////////////////////
8594
8595Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8596{
8597 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8598 return TClinginfo->Offset();
8599}
8600
8601////////////////////////////////////////////////////////////////////////////////
8602
8603Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8604{
8605 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8606 return TClinginfo->Property();
8607}
8608
8609////////////////////////////////////////////////////////////////////////////////
8610
8611Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8612{
8613 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8614 return TClinginfo->TypeProperty();
8615}
8616
8617////////////////////////////////////////////////////////////////////////////////
8618
8619int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8620{
8621 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8622 return TClinginfo->TypeSize();
8623}
8624
8625////////////////////////////////////////////////////////////////////////////////
8626
8627const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8628{
8629 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8630 return TClinginfo->TypeName();
8631}
8632
8633////////////////////////////////////////////////////////////////////////////////
8634
8635const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8636{
8637 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8638 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8639}
8640
8641////////////////////////////////////////////////////////////////////////////////
8642
8643const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8644{
8645 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8646 return TClinginfo->Name();
8647}
8648
8649////////////////////////////////////////////////////////////////////////////////
8650
8651const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8652{
8653 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8654 return TClinginfo->Title();
8655}
8656
8657////////////////////////////////////////////////////////////////////////////////
8658
8659const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8660{
8661 TTHREAD_TLS_DECL(std::string,result);
8662
8663 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8664 result = TClinginfo->ValidArrayIndex().str();
8665 return result.c_str(); // NOLINT
8666}
8667
8668////////////////////////////////////////////////////////////////////////////////
8669
8670void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8671{
8672 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8673 ASTContext &C = decl->getASTContext();
8674 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8675}
8676
8677//______________________________________________________________________________
8678//
8679// Function Template interface
8680//
8681
8682////////////////////////////////////////////////////////////////////////////////
8683
8684static void ConstructorName(std::string &name, const clang::Decl *decl,
8685 cling::Interpreter &interp,
8686 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8687{
8688 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8689 if (!td) return;
8690
8691 clang::QualType qualType(td->getTypeForDecl(),0);
8692 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8693 unsigned int level = 0;
8694 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8695 if (name[cursor] == '>') ++level;
8696 else if (name[cursor] == '<' && level) --level;
8697 else if (level == 0 && name[cursor] == ':') {
8698 name.erase(0,cursor+1);
8699 break;
8700 }
8701 }
8702}
8703
8704////////////////////////////////////////////////////////////////////////////////
8705
8706void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8707{
8708 output.clear();
8709
8710 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8711 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8712 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8713 }
8714 if (!FD) {
8715 Error("GetFunctionName", "NULL Decl!");
8716 return;
8717 }
8718
8719 // For using-decls, show "Derived", not "Base", i.e. use the
8720 // name of the decl context of the UsingShadowDecl (aka `decl`)
8721 // not the name of FD's decl context.
8722 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8723 {
8725
8726 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8727 {
8729 output.insert(output.begin(), '~');
8730 } else {
8731 llvm::raw_string_ostream stream(output);
8732 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8733 // Don't trigger fopen of the source file to count lines:
8734 printPolicy.AnonymousTagLocations = false;
8735 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8736 }
8737}
8738
8739////////////////////////////////////////////////////////////////////////////////
8740/// Return a unique identifier of the declaration represented by the
8741/// FuncTempInfo
8742
8744{
8745 return (DeclId_t)info;
8746}
8747
8748////////////////////////////////////////////////////////////////////////////////
8749/// Delete the FuncTempInfo_t
8750
8751void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8752{
8753 // Currently the address of ft_info is actually the decl itself,
8754 // so we have nothing to do.
8755}
8756
8757////////////////////////////////////////////////////////////////////////////////
8758/// Construct a FuncTempInfo_t
8759
8760FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8761{
8762 // Currently the address of ft_info is actually the decl itself,
8763 // so we have nothing to do.
8764
8765 return (FuncTempInfo_t*)const_cast<void*>(declid);
8766}
8767
8768////////////////////////////////////////////////////////////////////////////////
8769/// Construct a FuncTempInfo_t
8770
8771FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8772{
8773 // Currently the address of ft_info is actually the decl itself,
8774 // so we have nothing to do.
8775
8776 return (FuncTempInfo_t*)ft_info;
8777}
8778
8779////////////////////////////////////////////////////////////////////////////////
8780/// Check validity of a FuncTempInfo_t
8781
8782Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8783{
8784 // Currently the address of ft_info is actually the decl itself,
8785 // so we have nothing to do.
8786
8787 return t_info != nullptr;
8788}
8789
8790////////////////////////////////////////////////////////////////////////////////
8791/// Return the maximum number of template arguments of the
8792/// function template described by ft_info.
8793
8794UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8795{
8796 if (!ft_info) return 0;
8797 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8798 return ft->getTemplateParameters()->size();
8799}
8800
8801////////////////////////////////////////////////////////////////////////////////
8802/// Return the number of required template arguments of the
8803/// function template described by ft_info.
8804
8806{
8807 if (!ft_info) return 0;
8808 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8809 return ft->getTemplateParameters()->getMinRequiredArguments();
8810}
8811
8812////////////////////////////////////////////////////////////////////////////////
8813/// Return the property of the function template.
8814
8815Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8816{
8817 if (!ft_info) return 0;
8818
8819 long property = 0L;
8820 property |= kIsCompiled;
8821
8822 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8823
8824 switch (ft->getAccess()) {
8825 case clang::AS_public:
8826 property |= kIsPublic;
8827 break;
8828 case clang::AS_protected:
8829 property |= kIsProtected;
8830 break;
8831 case clang::AS_private:
8832 property |= kIsPrivate;
8833 break;
8834 case clang::AS_none:
8835 if (ft->getDeclContext()->isNamespace())
8837 break;
8838 default:
8839 // IMPOSSIBLE
8840 break;
8841 }
8842
8843 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8844 if (const clang::CXXMethodDecl *md =
8845 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8846 if (md->getMethodQualifiers().hasConst()) {
8847 property |= kIsConstant | kIsConstMethod;
8848 }
8849 if (md->isVirtual()) {
8850 property |= kIsVirtual;
8851 }
8852 if (md->isPure()) {
8853 property |= kIsPureVirtual;
8854 }
8855 if (const clang::CXXConstructorDecl *cd =
8856 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8857 if (cd->isExplicit()) {
8858 property |= kIsExplicit;
8859 }
8860 }
8861 else if (const clang::CXXConversionDecl *cd =
8862 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8863 if (cd->isExplicit()) {
8864 property |= kIsExplicit;
8865 }
8866 }
8867 }
8868 return property;
8869}
8870
8871////////////////////////////////////////////////////////////////////////////////
8872/// Return the property not already defined in Property
8873/// See TDictionary's EFunctionProperty
8874
8875Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8876{
8877 if (!ft_info) return 0;
8878
8879 long property = 0L;
8880 property |= kIsCompiled;
8881
8882 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8883 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8884
8885 if (fd->isOverloadedOperator())
8887 if (llvm::isa<clang::CXXConversionDecl>(fd))
8889 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8891 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8893 if (fd->isInlined())
8895 return property;
8896}
8897
8898////////////////////////////////////////////////////////////////////////////////
8899/// Return the name of this function template.
8900
8901void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8902{
8903 output.Clear();
8904 if (!ft_info) return;
8905 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8906 std::string buf;
8907 GetFunctionName(ft->getTemplatedDecl(), buf);
8908 output = buf;
8909}
8910
8911////////////////////////////////////////////////////////////////////////////////
8912/// Return the comments associates with this function template.
8913
8914void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8915{
8916 output.Clear();
8917 if (!ft_info) return;
8918 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8919
8920 // Iterate over the redeclarations, we can have multiple definitions in the
8921 // redecl chain (came from merging of pcms).
8922 if (const RedeclarableTemplateDecl *AnnotFD
8923 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8924 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8925 output = A->getAnnotation().str();
8926 return;
8927 }
8928 }
8929 if (!ft->isFromASTFile()) {
8930 // Try to get the comment from the header file if present
8931 // but not for decls from AST file, where rootcling would have
8932 // created an annotation
8934 }
8935}
8936
8937
8938//______________________________________________________________________________
8939//
8940// MethodInfo interface
8941//
8942
8943////////////////////////////////////////////////////////////////////////////////
8944/// Interface to cling function
8945
8946void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8947{
8948 delete(TClingMethodInfo*) minfo;
8949}
8950
8951////////////////////////////////////////////////////////////////////////////////
8952
8953void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8954{
8955 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8956 // The next call locks the interpreter mutex.
8957 info->CreateSignature(signature);
8958}
8959
8960////////////////////////////////////////////////////////////////////////////////
8961
8962MethodInfo_t* TCling::MethodInfo_Factory() const
8963{
8965 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8966}
8967
8968////////////////////////////////////////////////////////////////////////////////
8969
8970MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8971{
8973 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8974}
8975
8976////////////////////////////////////////////////////////////////////////////////
8977
8978MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8979{
8980 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8982 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
8983}
8984
8985////////////////////////////////////////////////////////////////////////////////
8986
8987MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
8988{
8989 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8990}
8991
8992////////////////////////////////////////////////////////////////////////////////
8993
8994void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
8995{
8996 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8997 // The next call locks the interpreter mutex.
8998 return info->InterfaceMethod();
8999}
9000
9001////////////////////////////////////////////////////////////////////////////////
9002
9003bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9004{
9005 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9006 return info->IsValid();
9007}
9008
9009////////////////////////////////////////////////////////////////////////////////
9010
9011int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9012{
9013 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9014 return info->NArg();
9015}
9016
9017////////////////////////////////////////////////////////////////////////////////
9018
9019int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9020{
9021 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9022 return info->NDefaultArg();
9023}
9024
9025////////////////////////////////////////////////////////////////////////////////
9026
9027int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9028{
9029 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9030 return info->Next();
9031}
9032
9033////////////////////////////////////////////////////////////////////////////////
9034
9035Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9036{
9037 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9038 // The next call locks the interpreter mutex.
9039 return info->Property();
9040}
9041
9042////////////////////////////////////////////////////////////////////////////////
9043
9045{
9046 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9047 // The next call locks the interpreter mutex.
9048 return info->ExtraProperty();
9049}
9050
9051////////////////////////////////////////////////////////////////////////////////
9052
9053TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9054{
9055 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9056 // The next call locks the interpreter mutex.
9057 return (TypeInfo_t*)info->Type();
9058}
9059
9060////////////////////////////////////////////////////////////////////////////////
9061
9062const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9063{
9064 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9065 TTHREAD_TLS_DECL(TString, mangled_name);
9066 // The next call locks the interpreter mutex.
9067 mangled_name = info->GetMangledName();
9068 return mangled_name;
9069}
9070
9071////////////////////////////////////////////////////////////////////////////////
9072
9073const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9074{
9075 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9076 // The next call locks the interpreter mutex.
9077 return info->GetPrototype();
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081
9082const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9083{
9084 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9085 // The next call locks the interpreter mutex.
9086 return info->Name();
9087}
9088
9089////////////////////////////////////////////////////////////////////////////////
9090
9091const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9092{
9093 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9094 // The next call locks the interpreter mutex.
9095 return info->TypeName();
9096}
9097
9098////////////////////////////////////////////////////////////////////////////////
9099
9100std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9101{
9102 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9103 // The next part locks the interpreter mutex.
9104 if (info && info->IsValid())
9105 return info->Type()->NormalizedName(*fNormalizedCtxt);
9106 else
9107 return "";
9108}
9109
9110////////////////////////////////////////////////////////////////////////////////
9111
9112const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9113{
9114 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9115 // The next call locks the interpreter mutex.
9116 return info->Title();
9117}
9118
9119////////////////////////////////////////////////////////////////////////////////
9120
9122{
9123 if (func) {
9124 return MethodInfo_MethodCallReturnType(func->fInfo);
9125 } else {
9126 return EReturnType::kOther;
9127 }
9128}
9129
9130////////////////////////////////////////////////////////////////////////////////
9131
9133{
9134 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9135 if (info && info->IsValid()) {
9136 TClingTypeInfo *typeinfo = info->Type();
9137 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9138 if (QT->isEnumeralType()) {
9139 return EReturnType::kLong;
9140 } else if (QT->isPointerType()) {
9141 // Look for char*
9142 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9143 if ( QT->isCharType() ) {
9144 return EReturnType::kString;
9145 } else {
9146 return EReturnType::kOther;
9147 }
9148 } else if ( QT->isFloatingType() ) {
9149 int sz = typeinfo->Size();
9150 if (sz == 4 || sz == 8) {
9151 // Support only float and double.
9152 return EReturnType::kDouble;
9153 } else {
9154 return EReturnType::kOther;
9155 }
9156 } else if ( QT->isIntegerType() ) {
9157 int sz = typeinfo->Size();
9158 if (sz <= 8) {
9159 // Support only up to long long ... but
9160 // FIXME the TMethodCall::Execute only
9161 // return long (4 bytes) ...
9162 // The v5 implementation of TMethodCall::ReturnType
9163 // was not making the distinction so we let it go
9164 // as is for now, but we really need to upgrade
9165 // TMethodCall::Execute ...
9166 return EReturnType::kLong;
9167 } else {
9168 return EReturnType::kOther;
9169 }
9170 } else {
9171 return EReturnType::kOther;
9172 }
9173 } else {
9174 return EReturnType::kOther;
9175 }
9176}
9177
9178//______________________________________________________________________________
9179//
9180// MethodArgInfo interface
9181//
9182
9183////////////////////////////////////////////////////////////////////////////////
9184
9185void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9186{
9187 delete(TClingMethodArgInfo*) marginfo;
9188}
9189
9190////////////////////////////////////////////////////////////////////////////////
9191
9192MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9193{
9195 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9196}
9197
9198////////////////////////////////////////////////////////////////////////////////
9199
9200MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9201{
9203 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9204}
9205
9206////////////////////////////////////////////////////////////////////////////////
9207
9208MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9209{
9210 return (MethodArgInfo_t*)
9212}
9213
9214////////////////////////////////////////////////////////////////////////////////
9215
9216bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9217{
9218 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9219 return info->IsValid();
9220}
9221
9222////////////////////////////////////////////////////////////////////////////////
9223
9224int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9225{
9226 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9227 return info->Next();
9228}
9229
9230////////////////////////////////////////////////////////////////////////////////
9231
9232Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9233{
9234 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9235 return info->Property();
9236}
9237
9238////////////////////////////////////////////////////////////////////////////////
9239
9240const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9241{
9242 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9243 return info->DefaultValue();
9244}
9245
9246////////////////////////////////////////////////////////////////////////////////
9247
9248const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9249{
9250 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9251 return info->Name();
9252}
9253
9254////////////////////////////////////////////////////////////////////////////////
9255
9256const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9257{
9258 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9259 return info->TypeName();
9260}
9261
9262////////////////////////////////////////////////////////////////////////////////
9263
9264std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9265{
9266 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9267 return info->Type()->NormalizedName(*fNormalizedCtxt);
9268}
9269
9270////////////////////////////////////////////////////////////////////////////////
9271
9272TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9273{
9274 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9275 return (TypeInfo_t*) info->Type();
9276}
9277
9278//______________________________________________________________________________
9279//
9280// TypeInfo interface
9281//
9282
9283////////////////////////////////////////////////////////////////////////////////
9284
9285void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9286{
9287 delete (TClingTypeInfo*) tinfo;
9288}
9289
9290////////////////////////////////////////////////////////////////////////////////
9291
9292TypeInfo_t* TCling::TypeInfo_Factory() const
9293{
9295 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9296}
9297
9298////////////////////////////////////////////////////////////////////////////////
9299
9300TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9301{
9303 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9304}
9305
9306////////////////////////////////////////////////////////////////////////////////
9307
9308TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9309{
9310 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9311}
9312
9313////////////////////////////////////////////////////////////////////////////////
9314
9315void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9316{
9318 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9319 TClinginfo->Init(name);
9320}
9321
9322////////////////////////////////////////////////////////////////////////////////
9323
9324bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9325{
9326 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9327 return TClinginfo->IsValid();
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331
9332const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9333{
9334 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9335 return TClinginfo->Name();
9336}
9337
9338////////////////////////////////////////////////////////////////////////////////
9339
9340Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9341{
9342 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9343 return TClinginfo->Property();
9344}
9345
9346////////////////////////////////////////////////////////////////////////////////
9347
9348int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9349{
9350 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9351 return TClinginfo->RefType();
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355
9356int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9357{
9358 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9359 return TClinginfo->Size();
9360}
9361
9362////////////////////////////////////////////////////////////////////////////////
9363
9364const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9365{
9366 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9367 return TClinginfo->TrueName(*fNormalizedCtxt);
9368}
9369
9370////////////////////////////////////////////////////////////////////////////////
9371
9372void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9373{
9374 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9375 return TClinginfo->QualTypePtr();
9376}
9377
9378
9379//______________________________________________________________________________
9380//
9381// TypedefInfo interface
9382//
9383
9384////////////////////////////////////////////////////////////////////////////////
9385
9386void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9387{
9388 delete(TClingTypedefInfo*) tinfo;
9389}
9390
9391////////////////////////////////////////////////////////////////////////////////
9392
9393TypedefInfo_t* TCling::TypedefInfo_Factory() const
9394{
9396 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9397}
9398
9399////////////////////////////////////////////////////////////////////////////////
9400
9401TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9402{
9404 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9405}
9406
9407////////////////////////////////////////////////////////////////////////////////
9408
9409TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9410{
9411 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9412}
9413
9414////////////////////////////////////////////////////////////////////////////////
9415
9416void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9417 const char* name) const
9418{
9420 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9421 TClinginfo->Init(name);
9422}
9423
9424////////////////////////////////////////////////////////////////////////////////
9425
9426bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9427{
9428 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9429 return TClinginfo->IsValid();
9430}
9431
9432////////////////////////////////////////////////////////////////////////////////
9433
9434Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9435{
9436 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9437 return TClinginfo->Next();
9438}
9439
9440////////////////////////////////////////////////////////////////////////////////
9441
9442Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9443{
9444 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9445 return TClinginfo->Property();
9446}
9447
9448////////////////////////////////////////////////////////////////////////////////
9449
9450int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9451{
9452 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9453 return TClinginfo->Size();
9454}
9455
9456////////////////////////////////////////////////////////////////////////////////
9457
9458const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9459{
9460 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9461 return TClinginfo->TrueName(*fNormalizedCtxt);
9462}
9463
9464////////////////////////////////////////////////////////////////////////////////
9465
9466const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9467{
9468 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9469 return TClinginfo->Name();
9470}
9471
9472////////////////////////////////////////////////////////////////////////////////
9473
9474const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9475{
9476 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9477 return TClinginfo->Title();
9478}
9479
9480////////////////////////////////////////////////////////////////////////////////
9481
9482bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9483{
9484 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9485 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9486 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9487}
9488
9489////////////////////////////////////////////////////////////////////////////////
9490
9491bool TCling::IsIntegerType(const void * QualTypePtr) const
9492{
9493 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9494 return QT->hasIntegerRepresentation();
9495}
9496
9497////////////////////////////////////////////////////////////////////////////////
9498
9499bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9500{
9501 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9502 return QT->hasSignedIntegerRepresentation();
9503}
9504
9505////////////////////////////////////////////////////////////////////////////////
9506
9507bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9508{
9509 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9510 return QT->hasUnsignedIntegerRepresentation();
9511}
9512
9513////////////////////////////////////////////////////////////////////////////////
9514
9515bool TCling::IsFloatingType(const void * QualTypePtr) const
9516{
9517 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9518 return QT->hasFloatingRepresentation();
9519}
9520
9521////////////////////////////////////////////////////////////////////////////////
9522
9523bool TCling::IsPointerType(const void * QualTypePtr) const
9524{
9525 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9526 return QT->hasPointerRepresentation();
9527}
9528
9529////////////////////////////////////////////////////////////////////////////////
9530
9531bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9532{
9533 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9534 return QT->isVoidPointerType();
9535}
9536
9537////////////////////////////////////////////////////////////////////////////////
9538
9540{
9541 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9542 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9543}
9544
9545////////////////////////////////////////////////////////////////////////////////
9546
9548{
9549 if (!fInitialMutex) {
9551 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9552 }
9554 }
9555 // We will "forget" this lock once we backed out of all interpreter frames.
9556 // Here we are entering one, so ++.
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561
9563{
9564 if (!fInitialMutex)
9565 return;
9566 if (fInitialMutex.fRecurseCount == 0) {
9567 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9568 }
9569 else if (--fInitialMutex.fRecurseCount == 0) {
9570 // We have returned from all interpreter frames. Reset the initial lock state.
9571 fInitialMutex.fState.reset();
9572 }
9573}
9574
9575////////////////////////////////////////////////////////////////////////////////
9576/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9577
9579{
9580 if (gInterpreterMutex) {
9581 if (delta) {
9582 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9583 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9584 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9585 // Now that we have the lock, update the global
9586 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9587 std::swap(fInitialMutex, typedDelta->fInitialState);
9588 } else {
9589 // This case happens when EnableThreadSafety is first called from
9590 // the interpreter function we just handled.
9591 // Since thread safety was not enabled at the time we rewound, there was
9592 // no lock taken and even-though we should be locking the rest of this
9593 // interpreter handling/modifying code (since there might be threads in
9594 // flight), we can't because there would not be any lock guard to release the
9595 // locks
9597 Error("ApplyToInterpreterMutex",
9598 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9599 "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.");
9600 }
9601 }
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605/// Reset the interpreter lock to the state it had before interpreter-related
9606/// calls happened.
9607
9609{
9610 if (fInitialMutex) {
9611 // Need to start a new recurse count.
9612 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9613 std::swap(uniqueP->fInitialState, fInitialMutex);
9614 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9615 return uniqueP.release();
9616 }
9618 return nullptr;
9619}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
RooAbsReal & function()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1308
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7198
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:6945
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:574
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:901
R__EXTERN int optind
Definition TCling.cxx:317
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:368
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:569
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:557
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:333
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:224
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3876
bool TCling__LibraryLoadingFailed(const std::string &errmessage, const std::string &libStem, bool permanent, bool resolved)
Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name, which is extracted by er...
Definition TCling.cxx:351
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1948
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3100
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition TCling.cxx:3918
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1089
bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname, std::string &result)
Try hard to avoid looking up in the Cling database as this could enduce an unwanted autoparsing.
Definition TCling.cxx:910
static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName=nullptr)
Checks if there is an ASTFile on disk for the given module M.
Definition TCling.cxx:1074
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:379
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:633
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1673
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:628
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:221
int TCling_GenerateDictionary(const std::vector< std::string > &classes, const std::vector< std::string > &headers, const std::vector< std::string > &fwdDecls, const std::vector< std::string > &unknown)
Definition TCling.cxx:699
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1088
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:251
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:593
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:564
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:604
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3894
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:588
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:389
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:215
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:644
#define R__DLLEXPORT
Definition TCling.cxx:151
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:360
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:233
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:623
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1039
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1192
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8684
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:326
static int HandleInterpreterException(cling::MetaProcessor *metaProcessor, const char *input_line, cling::Interpreter::CompilationResult &compRes, cling::Value *result)
Let cling process a command line.
Definition TCling.cxx:2432
static std::string GetSharedLibImmediateDepsSlow(std::string lib, cling::Interpreter *interp, bool skipLoadedLibs=true)
This interface returns a list of dependent libraries in the form: lib libA.so libB....
Definition TCling.cxx:7107
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:236
static clang::ClassTemplateDecl * FindTemplateInNamespace(clang::Decl *decl)
Find a template decl within N nested namespaces, 0<=N<inf Assumes 1 and only 1 template present and 1...
Definition TCling.cxx:680
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1973
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:608
const char * fantomline
Definition TCling.cxx:848
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:583
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6284
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5464
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:218
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:600
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program.
Definition TCling.cxx:1061
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:639
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:616
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7219
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:651
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
#define gDirectory
Definition TDirectory.h:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:595
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
@ kReadPermission
Definition TSystem.h:45
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:116
R__EXTERN TSystem * gSystem
Definition TSystem.h:555
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17536
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3439
EState GetState() const
Definition TClass.h:486
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2886
EState fState
cached of the streaming method to use
Definition TClass.h:275
std::atomic< TList * > fBase
Definition TClass.h:202
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:222
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3798
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition TClass.cxx:4915
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:536
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2205
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:206
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3398
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5959
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5749
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5704
@ kLoading
Definition TClass.h:330
@ kUnloading
Definition TClass.h:330
TObjArray * fStreamerInfo
Definition TClass.h:199
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
ClassInfo_t * GetClassInfo() const
Definition TClass.h:431
ClassInfo_t * fClassInfo
Definition TClass.h:223
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4215
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1820
@ kInterpreted
Definition TClass.h:127
@ kHasTClassInit
Definition TClass.h:128
@ kEmulated
Definition TClass.h:126
@ kForwardDeclared
Definition TClass.h:125
@ kNamespaceForMeta
Definition TClass.h:132
Version_t GetClassVersion() const
Definition TClass.h:418
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:257
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3463
@ kIsTObject
Definition TClass.h:100
@ kIsEmulation
Definition TClass.h:102
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void ExecWithReturn(void *address, void *ret=nullptr)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
bool IsValid() const
Longptr_t ExecInt(void *address)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
void IgnoreExtraArgs(bool ignore)
void SetArg(T arg)
long long ExecInt64(void *address)
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() const
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1015
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1023
std::string fContent
Definition TCling.h:619
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6156
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9240
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8247
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9332
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:8994
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4344
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3856
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9426
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6217
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7885
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:3619
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6520
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7402
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7811
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9053
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7788
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:7445
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3695
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8670
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:496
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Invalidate cached TCling information for the given declaration, and removed it from the appropriate o...
Definition TCling.cxx:6840
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9035
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4391
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8281
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8603
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7530
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:4438
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3740
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8273
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6714
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9348
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4320
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8160
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9082
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8417
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:3989
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7460
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7235
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9132
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7659
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3531
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9003
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8760
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9292
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7499
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6825
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7623
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7608
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3319
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9474
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:8010
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5607
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:6475
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9539
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1820
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4456
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1627
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7712
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2628
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8437
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6587
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7862
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7846
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7911
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5415
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3143
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3843
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7877
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9578
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6543
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:4675
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:8076
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3109
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:7424
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8529
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9272
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8563
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3636
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:5480
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8297
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7551
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9216
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9356
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3754
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7432
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7587
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:8794
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:5107
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9393
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9531
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2462
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8345
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9256
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:644
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5355
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8587
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9466
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8410
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9044
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3523
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7041
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8771
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8579
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8782
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:2642
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8232
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3654
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8627
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4902
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:7967
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8057
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9608
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9248
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3118
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9416
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8651
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7830
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3056
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:7481
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:7302
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7869
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9507
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9409
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:5000
void UnRegisterTClassUpdate(const TClass *oldcl) final
If the dictionary is loaded, we can remove the class from the list (otherwise the class might be load...
Definition TCling.cxx:2402
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9264
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:4784
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9232
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9450
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7819
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:5152
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:634
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6694
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3486
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9434
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:4959
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9315
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7541
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8619
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8387
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8643
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5430
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9499
void ForgetMutexState() final
Definition TCling.cxx:9562
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9027
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8121
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:8946
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9185
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8544
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8152
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:6062
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5950
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8214
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8482
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7838
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8337
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8461
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:421
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5337
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7288
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7365
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6900
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8815
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9364
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:5968
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7632
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6938
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9224
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9547
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9340
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9073
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:8805
std::vector< cling::Value > * fTemporaries
Definition TCling.h:133
void RegisterModule(const char *modulename, const char **headers, const char **includePaths, const char *payloadCode, const char *fwdDeclsCode, void(*triggerFunc)(), const FwdDeclArgsToKeepCollection_t &fwdDeclsArgToSkip, const char **classesHeaders, Bool_t lateRegistration=false, Bool_t hasCxxModule=false) final
Inject the module named "modulename" into cling; load all headers.
Definition TCling.cxx:2019
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6108
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:8953
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4298
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6923
void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict) final
Register classes that already existed prior to their dictionary loading and that already had a ClassI...
Definition TCling.cxx:2393
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8571
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8240
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9019
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4447
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5877
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:7560
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9062
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9491
std::hash< std::string > fStringHashFunction
Definition TCling.h:124
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:591
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5062
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8305
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7356
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8706
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4472
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7347
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9208
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8453
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:4126
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7394
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3386
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9285
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9011
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4893
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9121
void ProcessClassesToUpdate()
Definition TCling.cxx:1989
DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return pointer to cling DeclId for a method of a class with a certain prototype, i....
Definition TCling.cxx:5085
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:4914
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9112
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8516
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:3069
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8498
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:7975
int UnloadFile(const char *path) const final
Definition TCling.cxx:7593
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7795
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9523
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9515
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8875
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7894
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8508
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8659
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4493
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1032
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4824
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5185
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8265
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8353
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8474
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:7983
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4427
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8361
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8914
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8395
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3830
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1705
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6579
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:3711
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7615
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:3725
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7468
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3556
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5889
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3863
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8537
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:5368
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:4465
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:2664
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6030
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:8987
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7903
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9192
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6688
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:4981
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8129
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8256
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8751
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:5129
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3769
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8595
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7854
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:8962
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8611
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3048
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2451
void SetAllocunlockfunc(void(*)()) const final
[Place holder for Mutex Unlock] Provide the interpreter with a way to release a lock used to protect ...
Definition TCling.cxx:7491
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2367
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9386
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3679
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9458
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7512
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8369
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:6333
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9091
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7919
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7316
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6798
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6630
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9482
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1645
int ClassInfo_GetMethodNArg(ClassInfo_t *info, const char *method, const char *proto, Bool_t objectIsConst=false, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8190
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:4723
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:8901
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9324
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1915
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9100
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8379
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4503
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8198
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3092
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9308
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9372
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8206
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8144
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:8635
virtual void ShutDown() final
Definition TCling.cxx:1664
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3870
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9442
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1687
Longptr_t ProcessLineSynch(const char *line, EErrorCode *error=nullptr) final
Let cling process a command line synchronously, i.e we are waiting it will be finished.
Definition TCling.cxx:3540
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:4941
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6703
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5693
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8490
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6930
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add(TObject *obj)=0
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:212
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h:63
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:175
DeclId_t GetDeclId() const
Definition TEnum.cxx:146
@ kNone
Definition TEnum.h:48
@ kAutoload
Definition TEnum.h:49
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
THashList * GetTable() const
Definition TEnv.h:140
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:793
virtual void SetRcName(const char *name)
Definition TEnv.h:145
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:592
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:547
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
Definition TFile.h:53
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * Remove(TObject *obj) override
Remove object from the list.
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
This class defines an abstract interface to a generic command line interpreter.
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
virtual const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:307
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
TNamed()
Definition TNamed.h:36
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Clear(Option_t *option="") override
Remove all objects from the array.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:962
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:976
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1004
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
virtual TClass * IsA() const
Definition TObject.h:245
void MakeZombie()
Definition TObject.h:53
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:950
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:2995
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2734
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2905
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3005
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2915
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:2984
Sequenceable collection abstract base class.
Int_t LastIndex() const
void Add(TObject *obj) override
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:931
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:572
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1665
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3973
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4258
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1071
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1538
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2489
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1795
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2034
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition TSystem.cxx:2836
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:871
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1649
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:887
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2020
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TLine * line
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:188
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:183
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:184
std::string InsertStd(const char *tname)
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h:208
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:125
Long_t fMemVirtual
Definition TSystem.h:194
Long_t fMemResident
Definition TSystem.h:193
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::vector< std::string > fElements
Definition TClassEdit.h:141
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:157
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:162
A read-only memory range which we do not control.
Definition TMemFile.h:23
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static void output()