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
148#ifndef R__WIN32
149#include <cxxabi.h>
150#define R__DLLEXPORT __attribute__ ((visibility ("default")))
151#include <sys/stat.h>
152#endif
153#include <limits.h>
154#include <stdio.h>
155
156#ifdef __APPLE__
157#include <dlfcn.h>
158#include <mach-o/dyld.h>
159#include <mach-o/loader.h>
160#endif // __APPLE__
161
162#ifdef R__UNIX
163#include <dlfcn.h>
164#endif
165
166#ifdef R__LINUX
167# ifndef _GNU_SOURCE
168# define _GNU_SOURCE
169# endif
170# include <link.h> // dl_iterate_phdr()
171#endif
172
173#if defined(__CYGWIN__)
174#include <sys/cygwin.h>
175#define HMODULE void *
176extern "C" {
177 __declspec(dllimport) void * __stdcall GetCurrentProcess();
178 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
179 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
180}
181#endif
182
183// Fragment copied from LLVM's raw_ostream.cpp
184#if defined(_MSC_VER)
185#ifndef STDIN_FILENO
186# define STDIN_FILENO 0
187#endif
188#ifndef STDOUT_FILENO
189# define STDOUT_FILENO 1
190#endif
191#ifndef STDERR_FILENO
192# define STDERR_FILENO 2
193#endif
194#ifndef R__WIN32
195//#if defined(HAVE_UNISTD_H)
196# include <unistd.h>
197//#endif
198#else
199#include "Windows4Root.h"
200#include <Psapi.h>
201#undef GetModuleFileName
202#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
203#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
204#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
205#define dlclose(library) ::FreeLibrary((HMODULE)library)
206#define R__DLLEXPORT __declspec(dllexport)
207#endif
208#endif
209
210//______________________________________________________________________________
211// These functions are helpers for debugging issues with non-LLVMDEV builds.
212//
213R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
214 return D->getDeclContext();
215}
216R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
217 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
218}
219R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
220 return llvm::dyn_cast<clang::RecordDecl>(DC);
221}
222R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
223 return DC->dumpDeclContext();
224}
225R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
226 return D->dump();
227}
228R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
229 return FD->dump();
230}
232 return ((clang::Decl*)D)->dump();
233}
235 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
236 std::string name;
237 {
238 llvm::raw_string_ostream OS(name);
239 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
240 true /*Qualified*/);
241 }
242 printf("%s\n", name.c_str());
243 }
244}
245//______________________________________________________________________________
246// These functions are helpers for testing issues directly rather than
247// relying on side effects.
248// This is used for the test for ROOT-7462/ROOT-6070
250 return D->isInvalidDecl();
251}
254 assert(info && info->IsValid());
255 return info->GetDecl()->isInvalidDecl();
256}
257
258using namespace std;
259using namespace clang;
260using namespace ROOT;
261
262namespace {
263 static const std::string gInterpreterClassDef = R"ICF(
264#undef ClassDef
265#define ClassDef(name, id) \
266_ClassDefInterp_(name,id,virtual,) \
267static int DeclFileLine() { return __LINE__; }
268#undef ClassDefNV
269#define ClassDefNV(name, id) \
270_ClassDefInterp_(name,id,,) \
271static int DeclFileLine() { return __LINE__; }
272#undef ClassDefOverride
273#define ClassDefOverride(name, id) \
274_ClassDefInterp_(name,id,,override) \
275static int DeclFileLine() { return __LINE__; }
276)ICF";
277
278 static const std::string gNonInterpreterClassDef = R"ICF(
279#define __ROOTCLING__ 1
280#undef ClassDef
281#define ClassDef(name,id) \
282_ClassDefOutline_(name,id,virtual,) \
283static int DeclFileLine() { return __LINE__; }
284#undef ClassDefNV
285#define ClassDefNV(name, id)\
286_ClassDefOutline_(name,id,,)\
287static int DeclFileLine() { return __LINE__; }
288#undef ClassDefOverride
289#define ClassDefOverride(name, id)\
290_ClassDefOutline_(name,id,,override)\
291static int DeclFileLine() { return __LINE__; }
292)ICF";
293
294// The macros below use ::Error, so let's ensure it is included
295 static const std::string gClassDefInterpMacro = R"ICF(
296#include "TError.h"
297
298#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
299private: \
300public: \
301 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
302 static const char *Class_Name() { return #name; } \
303 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
304 static Version_t Class_Version() { return id; } \
305 static TClass *Dictionary() { return 0; } \
306 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
307 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
308 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
309 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
310 static const char *DeclFileName() { return __FILE__; } \
311 static int ImplFileLine() { return 0; } \
312 static const char *ImplFileName() { return __FILE__; }
313)ICF";
314}
316
317// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
318// ROOT (which uses rtti)
319
320////////////////////////////////////////////////////////////////////////////////
321/// Print a StackTrace!
322
323extern "C"
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Load a library.
330
331extern "C" int TCling__LoadLibrary(const char *library)
332{
333 return gSystem->Load(library, "", false);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
338
339extern "C" void TCling__RestoreInterpreterMutex(void *delta)
340{
341 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
346/// which is extracted by error messages we get from callback from cling. Return true
347/// when the missing library was autoloaded.
348
349extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
350{
351 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Reset the interpreter lock to the state it had before interpreter-related
356/// calls happened.
357
359{
360 return ((TCling*)gCling)->RewindInterpreterMutex();
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// Lock the interpreter.
365
367{
368 if (gInterpreterMutex) {
370 }
371 return nullptr;
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Unlock the interpreter.
376
378{
379 if (gInterpreterMutex) {
381 }
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
386
387static void TCling__UpdateClassInfo(const NamedDecl* TD)
388{
389 static Bool_t entered = kFALSE;
390 static vector<const NamedDecl*> updateList;
391 Bool_t topLevel;
392
393 if (entered) topLevel = kFALSE;
394 else {
395 entered = kTRUE;
396 topLevel = kTRUE;
397 }
398 if (topLevel) {
399 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
400 } else {
401 // If we are called indirectly from within another call to
402 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
403 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
404 // This allows for the dictionary to be fully populated when we actually
405 // update the TClass object. The updating of the TClass sometimes
406 // (STL containers and when there is an emulated class) forces the building
407 // of the TClass object's real data (which needs the dictionary info).
408 updateList.push_back(TD);
409 }
410 if (topLevel) {
411 while (!updateList.empty()) {
412 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
413 updateList.pop_back();
414 }
415 entered = kFALSE;
416 }
417}
418
419void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
420 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
421 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
422 // Add the constants to the enum type.
423 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
424 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
425 // Get name of the enum type.
426 std::string constbuf;
427 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
428 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
429 llvm::raw_string_ostream stream(constbuf);
430 // Don't trigger fopen of the source file to count lines:
431 Policy.AnonymousTagLocations = false;
432 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
433 }
434 const char* constantName = constbuf.c_str();
435
436 // Get value of the constant.
438 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
439 if (valAPSInt.isSigned()) {
440 value = valAPSInt.getSExtValue();
441 } else {
442 value = valAPSInt.getZExtValue();
443 }
444
445 // Create the TEnumConstant or update it if existing
446 TEnumConstant* enumConstant = nullptr;
447 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
448 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
449 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
450 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
451 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
452 } else {
453 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
454 }
455
456 // Add the global constants to the list of Globals.
457 if (!cl) {
458 TCollection* globals = gROOT->GetListOfGlobals(false);
459 if (!globals->FindObject(constantName)) {
460 globals->Add(enumConstant);
461 }
462 }
463 }
464 }
465}
466
467TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
468{
469 // Handle new enum declaration for either global and nested enums.
470
471 // Create the enum type.
472 TEnum* enumType = 0;
473 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
474 std::string buf;
475 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
476 // Get name of the enum type.
477 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
478 llvm::raw_string_ostream stream(buf);
479 // Don't trigger fopen of the source file to count lines:
480 Policy.AnonymousTagLocations = false;
481 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
482 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
483 }
484 if (buf.empty()) {
485 return 0;
486 }
487 const char* name = buf.c_str();
488 enumType = new TEnum(name, VD, cl);
489 UpdateEnumConstants(enumType, cl);
490
491 return enumType;
492}
493
494void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
495 // Handle new declaration.
496 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
497
498 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
499
500 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
501 && !dyn_cast<clang::RecordDecl>(D)) return;
502
503 if (isa<clang::FunctionDecl>(D->getDeclContext())
504 || isa<clang::TagDecl>(D->getDeclContext()))
505 return;
506
507 // Don't list templates.
508 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
509 if (RD->getDescribedClassTemplate())
510 return;
511 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
512 if (FD->getDescribedFunctionTemplate())
513 return;
514 }
515
516 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
517 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
519 }
520 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
521
522 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
523 // Mostly just for EnumDecl (the other TagDecl are handled
524 // by the 'RecordDecl' if statement.
526 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
528 }
529
530 // We care about declarations on the global scope.
531 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
532 return;
533
534 // Enums are lazyly created, thus we don not need to handle them here.
535 if (isa<EnumDecl>(ND))
536 return;
537
538 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
539 // scope.
540 if (!(isa<VarDecl>(ND)))
541 return;
542
543 // Skip if already in the list.
544 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
545 return;
546
547 // Put the global constants and global enums in the corresponding lists.
548 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
550 cast<ValueDecl>(ND), 0)));
551 }
552}
553
554extern "C"
556{
557 // We are sure in this context of the type of the interpreter
558 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
559}
560
561extern "C"
562void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
563 ((TCling*)gCling)->UpdateListsOnCommitted(T);
564}
565
566extern "C"
567void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
568 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
569}
570
571extern "C"
572void TCling__InvalidateGlobal(const clang::Decl *D) {
573 ((TCling*)gCling)->InvalidateGlobal(D);
574}
575
576extern "C"
577void TCling__TransactionRollback(const cling::Transaction &T) {
578 ((TCling*)gCling)->TransactionRollback(T);
579}
580
581extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
582 const char* canonicalName) {
583 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
584}
585
586extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
587{
588 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
589}
590
591extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
592 const char* canonicalName) {
593 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
594}
595
596
597extern "C"
598TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
599 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
600}
601
602extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
603 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
604}
605
606extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
607 const char* argv[])
608{
609 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
610
611 return tcling;
612}
613
615{
616 delete interp;
617}
618
619// Load library containing specified class. Returns 0 in case of error
620// and 1 in case if success.
621extern "C" int TCling__AutoLoadCallback(const char* className)
622{
623 return ((TCling*)gCling)->AutoLoad(className);
624}
625
626extern "C" int TCling__AutoParseCallback(const char* className)
627{
628 return ((TCling*)gCling)->AutoParse(className);
629}
630
631extern "C" const char* TCling__GetClassSharedLibs(const char* className)
632{
633 return ((TCling*)gCling)->GetClassSharedLibs(className);
634}
635
636// Returns 0 for failure 1 for success
637extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
638{
639 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
640}
641
642extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
643{
644 string file(fileName);
645 string opt(options);
646 return gSystem->CompileMacro(file.c_str(), opt.c_str());
647}
648
649extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
650 string &args, string &io, string &fname)
651{
652 string file(fileName);
653 TString f, amode, arguments, aclicio;
654 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
655 mode = amode.Data(); args = arguments.Data();
656 io = aclicio.Data(); fname = f.Data();
657}
658
659//______________________________________________________________________________
660//
661//
662//
663
664#ifdef R__WIN32
665extern "C" {
666 char *__unDName(char *demangled, const char *mangled, int out_len,
667 void * (* pAlloc )(size_t), void (* pFree )(void *),
668 unsigned short int flags);
669}
670#endif
671
672////////////////////////////////////////////////////////////////////////////////
673/// Find a template decl within N nested namespaces, 0<=N<inf
674/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
675/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
676/// Returns nullptr in case of error
677
678static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
679{
680 using namespace clang;
681 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
682 return FindTemplateInNamespace(*nsd->decls_begin());
683 }
684
685 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
686 return ctd;
687 }
688
689 return nullptr; // something went wrong.
690}
691
692//______________________________________________________________________________
693//
694//
695//
696
697int TCling_GenerateDictionary(const std::vector<std::string> &classes,
698 const std::vector<std::string> &headers,
699 const std::vector<std::string> &fwdDecls,
700 const std::vector<std::string> &unknown)
701{
702 //This function automatically creates the "LinkDef.h" file for templated
703 //classes then executes CompileMacro on it.
704 //The name of the file depends on the class name, and it's not generated again
705 //if the file exist.
706 if (classes.empty()) {
707 return 0;
708 }
709 // Use the name of the first class as the main name.
710 const std::string& className = classes[0];
711 //(0) prepare file name
712 TString fileName = "AutoDict_";
713 std::string::const_iterator sIt;
714 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
715 if (*sIt == '<' || *sIt == '>' ||
716 *sIt == ' ' || *sIt == '*' ||
717 *sIt == ',' || *sIt == '&' ||
718 *sIt == ':') {
719 fileName += '_';
720 }
721 else {
722 fileName += *sIt;
723 }
724 }
725 if (classes.size() > 1) {
726 Int_t chk = 0;
727 std::vector<std::string>::const_iterator it = classes.begin();
728 while ((++it) != classes.end()) {
729 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
730 chk = chk * 3 + it->at(cursor);
731 }
732 }
733 fileName += TString::Format("_%u", chk);
734 }
735 fileName += ".cxx";
736 if (gSystem->AccessPathName(fileName) != 0) {
737 //file does not exist
738 //(1) prepare file data
739 // If STL, also request iterators' operators.
740 // vector is special: we need to check whether
741 // vector::iterator is a typedef to pointer or a
742 // class.
743 static const std::set<std::string> sSTLTypes {
744 "vector","list","forward_list","deque","map","unordered_map","multimap",
745 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
746 "queue","priority_queue","stack","iterator"};
747 std::vector<std::string>::const_iterator it;
748 std::string fileContent("");
749 for (it = headers.begin(); it != headers.end(); ++it) {
750 fileContent += "#include \"" + *it + "\"\n";
751 }
752 for (it = unknown.begin(); it != unknown.end(); ++it) {
753 TClass* cl = TClass::GetClass(it->c_str());
754 if (cl && cl->GetDeclFileName()) {
755 TString header = gSystem->BaseName(cl->GetDeclFileName());
757 TString dirbase(gSystem->BaseName(dir));
758 while (dirbase.Length() && dirbase != "."
759 && dirbase != "include" && dirbase != "inc"
760 && dirbase != "prec_stl") {
761 gSystem->PrependPathName(dirbase, header);
762 dir = gSystem->GetDirName(dir);
763 }
764 fileContent += TString("#include \"") + header + "\"\n";
765 }
766 }
767 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
768 fileContent += "class " + *it + ";\n";
769 }
770 fileContent += "#ifdef __CLING__ \n";
771 fileContent += "#pragma link C++ nestedclasses;\n";
772 fileContent += "#pragma link C++ nestedtypedefs;\n";
773 for (it = classes.begin(); it != classes.end(); ++it) {
774 std::string n(*it);
775 size_t posTemplate = n.find('<');
776 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
777 if (posTemplate != std::string::npos) {
778 n.erase(posTemplate, std::string::npos);
779 if (n.compare(0, 5, "std::") == 0) {
780 n.erase(0, 5);
781 }
782 iSTLType = sSTLTypes.find(n);
783 }
784 fileContent += "#pragma link C++ class ";
785 fileContent += *it + "+;\n" ;
786 fileContent += "#pragma link C++ class ";
787 if (iSTLType != sSTLTypes.end()) {
788 // STL class; we cannot (and don't need to) store iterators;
789 // their shadow and the compiler's version don't agree. So
790 // don't ask for the '+'
791 fileContent += *it + "::*;\n" ;
792 }
793 else {
794 // Not an STL class; we need to allow the I/O of contained
795 // classes (now that we have a dictionary for them).
796 fileContent += *it + "::*+;\n" ;
797 }
798 }
799 fileContent += "#endif\n";
800 //end(1)
801 //(2) prepare the file
802 FILE* filePointer;
803 filePointer = fopen(fileName, "w");
804 if (filePointer == NULL) {
805 //can't open a file
806 return 1;
807 }
808 //end(2)
809 //write data into the file
810 fprintf(filePointer, "%s", fileContent.c_str());
811 fclose(filePointer);
812 }
813 //(3) checking if we can compile a macro, if not then cleaning
814 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
815 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
816 Int_t ret = gSystem->CompileMacro(fileName, "k");
817 gErrorIgnoreLevel = oldErrorIgnoreLevel;
818 if (ret == 0) { //can't compile a macro
819 return 2;
820 }
821 //end(3)
822 return 0;
823}
824
825int TCling_GenerateDictionary(const std::string& className,
826 const std::vector<std::string> &headers,
827 const std::vector<std::string> &fwdDecls,
828 const std::vector<std::string> &unknown)
829{
830 //This function automatically creates the "LinkDef.h" file for templated
831 //classes then executes CompileMacro on it.
832 //The name of the file depends on the class name, and it's not generated again
833 //if the file exist.
834 std::vector<std::string> classes;
835 classes.push_back(className);
836 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
837}
838
839//______________________________________________________________________________
840//
841//
842//
843
844// It is a "fantom" method to synchronize user keyboard input
845// and ROOT prompt line (for WIN32)
846const char* fantomline = "TRint::EndOfLineAction();";
847
848//______________________________________________________________________________
849//
850//
851//
852
854
855//______________________________________________________________________________
856//
857// llvm error handler through exceptions; see also cling/UserInterface
858//
859namespace {
860 // Handle fatal llvm errors by throwing an exception.
861 // Yes, throwing exceptions in error handlers is bad.
862 // Doing nothing is pretty terrible, too.
863 void exceptionErrorHandler(void * /*user_data*/,
864 const std::string& reason,
865 bool /*gen_crash_diag*/) {
866 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
867 }
868}
869
870//______________________________________________________________________________
871//
872//
873//
874
875////////////////////////////////////////////////////////////////////////////////
876
877namespace{
878 // An instance of this class causes the diagnostics of clang to be suppressed
879 // during its lifetime
880 class clangDiagSuppr {
881 public:
882 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
883 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
884 fDiagEngine.setIgnoreAllWarnings(true);
885 }
886
887 ~clangDiagSuppr() {
888 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
889 }
890 private:
891 clang::DiagnosticsEngine& fDiagEngine;
892 bool fOldDiagValue;
893 };
894
895}
896
897////////////////////////////////////////////////////////////////////////////////
898/// Allow calling autoparsing from TMetaUtils
900{
901 return gCling->AutoParse(cname);
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Try hard to avoid looking up in the Cling database as this could enduce
906/// an unwanted autoparsing.
907
908bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
909 std::string &result)
910{
911 result.clear();
912
913 unsigned long offset = 0;
914 if (strncmp(tname.c_str(), "const ", 6) == 0) {
915 offset = 6;
916 }
917 unsigned long end = tname.length();
918 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
919 if ( tname[end-1]==']' ) {
920 --end;
921 while ( end && tname[end-1]!='[' ) --end;
922 }
923 --end;
924 }
925 std::string innerbuf;
926 const char *inner;
927 if (end != tname.length()) {
928 innerbuf = tname.substr(offset,end-offset);
929 inner = innerbuf.c_str();
930 } else {
931 inner = tname.c_str()+offset;
932 }
933
934 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
935 if (gROOT->GetListOfClasses()->FindObject(inner)
936 || TClassTable::Check(inner,result) ) {
937 // This is a known class.
938 return true;
939 }
940
941 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
942 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
943 if (type) {
944 // This is a raw type and an already loaded typedef.
945 const char *newname = type->GetFullTypeName();
946 if (type->GetType() == kLong64_t) {
947 newname = "Long64_t";
948 } else if (type->GetType() == kULong64_t) {
949 newname = "ULong64_t";
950 }
951 if (strcmp(inner,newname) == 0) {
952 return true;
953 }
954 if (offset) result = "const ";
955 result += newname;
956 if ( end != tname.length() ) {
957 result += tname.substr(end,tname.length()-end);
958 }
959 if (result == tname) result.clear();
960 return true;
961 }
962
963 // Check if the name is an enumerator
964 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
965 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
966 {
967 // We have a scope
968 // All of this C gymnastic is to avoid allocations on the heap
969 const auto enName = lastPos;
970 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
971 char *scopeName = new char[scopeNameSize + 1];
972 strncpy(scopeName, inner, scopeNameSize);
973 scopeName[scopeNameSize] = '\0';
974 // Check if the scope is in the list of classes
975 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
976 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
977 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
978 }
979 // It may still be in one of the loaded protoclasses
980 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
981 auto listOfEnums = scope->GetListOfEnums();
982 if (listOfEnums) { // it could be null: no enumerators in the protoclass
983 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
984 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
985 }
986 }
987 delete [] scopeName;
988 } else
989 {
990 // We don't have any scope: this could only be a global enum
991 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
992 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
993 }
994
995 if (gCling->GetClassSharedLibs(inner))
996 {
997 // This is a class name.
998 return true;
999 }
1000
1001 return false;
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005
1007{
1008 fContent.reserve(size);
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012
1014{
1015 return fContent.c_str();
1016}
1017
1018////////////////////////////////////////////////////////////////////////////////
1019/// Append string to the storage if not added already.
1020
1021inline bool TCling::TUniqueString::Append(const std::string& str)
1022{
1023 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1024 if (notPresent){
1025 fContent+=str;
1026 }
1027 return notPresent;
1028}
1029
1030std::string TCling::ToString(const char* type, void* obj)
1031{
1032 return fInterpreter->toString(type, obj);
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036///\returns true if the module was loaded.
1037static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1038{
1039 // When starting up ROOT, cling would load all modulemap files on the include
1040 // paths. However, in a ROOT session, it is very common to run aclic which
1041 // will invoke rootcling and possibly produce a modulemap and a module in
1042 // the current folder.
1043 //
1044 // Before failing, try loading the modulemap in the current folder and try
1045 // loading the requested module from it.
1046 std::string currentDir = gSystem->WorkingDirectory();
1047 assert(!currentDir.empty());
1049 if (gDebug > 2)
1050 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1051 ModuleName.c_str());
1052
1053 return interp.loadModule(ModuleName, /*Complain=*/true);
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Loads the C++ modules that we require to run any ROOT program. This is just
1058/// supposed to make a C++ module from a modulemap available to the interpreter.
1059static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1060{
1061 for (const auto &modName : modules)
1062 LoadModule(modName, interp);
1063}
1064
1065static bool IsFromRootCling() {
1066 // rootcling also uses TCling for generating the dictionary ROOT files.
1067 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1068 return foundSymbol;
1069}
1070
1071/// Checks if there is an ASTFile on disk for the given module \c M.
1072static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1073{
1074 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1075
1076 std::string ModuleFileName;
1077 if (!HSOpts.PrebuiltModulePaths.empty())
1078 // Load the module from *only* in the prebuilt module path.
1079 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1080 if (FullFileName)
1081 *FullFileName = ModuleFileName;
1082
1083 return !ModuleFileName.empty();
1084}
1085
1086static bool HaveFullGlobalModuleIndex = false;
1087static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1088{
1089 CompilerInstance &CI = *interp.getCI();
1090 Preprocessor &PP = CI.getPreprocessor();
1091 auto ModuleManager = CI.getASTReader();
1092 assert(ModuleManager);
1093 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1094 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1095 // HSI.setModuleCachePath(TROOT::GetLibDir().Data());
1096 std::string ModuleIndexPath = TROOT::GetLibDir().Data();
1097 if (ModuleIndexPath.empty())
1098 return nullptr;
1099 // Get an existing global index. This loads it if not already loaded.
1100 ModuleManager->resetForReload();
1101 ModuleManager->loadGlobalIndex();
1102 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1103
1104 // For finding modules needing to be imported for fixit messages,
1105 // we need to make the global index cover all modules, so we do that here.
1106 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1107 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1108 bool RecreateIndex = false;
1109 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1110 Module *TheModule = I->second;
1111 // We want the index only of the prebuilt modules.
1112 if (!HasASTFileOnDisk(TheModule, PP))
1113 continue;
1114 LoadModule(TheModule->Name, interp);
1115 RecreateIndex = true;
1116 }
1117 if (RecreateIndex) {
1118 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1119 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1120
1121 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1122 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1123 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1124 TraverseDecl(TU);
1125 }
1126 bool VisitNamedDecl(NamedDecl *ND) {
1127 if (!ND->isFromASTFile())
1128 return true;
1129 if (!ND->getIdentifier())
1130 return true;
1131
1132 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1133 return true;
1134
1135 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1136 if (TD->isCompleteDefinition())
1137 Register(TD);
1138 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1139 Register(NSD, /*AddSingleEntry=*/ false);
1140 }
1141 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1142 Register(TND);
1143 // FIXME: Add the rest...
1144 return true; // continue decending
1145 }
1146 private:
1147 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1148 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1149 assert(ND->isFromASTFile());
1150 // FIXME: All decls should have an owning module once rootcling
1151 // updates its generated decls from within the LookupHelper & co.
1152 if (!ND->hasOwningModule()) {
1153#ifndef NDEBUG
1154 SourceManager &SM = ND->getASTContext().getSourceManager();
1155 SourceLocation Loc = ND->getLocation();
1156 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1157 (void)FE;
1158 assert(FE->getName().contains("input_line_"));
1159#endif
1160 return;
1161 }
1162
1163 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1164 assert(OwningModule);
1165 assert(!ND->getName().empty() && "Empty name");
1166 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1167 return;
1168 // FIXME: The FileEntry in not stable to serialize.
1169 // FIXME: We might end up with many times with the same module.
1170 // FIXME: We might end up two modules containing a definition.
1171 // FIXME: What do we do if no definition is found.
1172 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1173 }
1174 };
1175 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1176
1177 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1178 CI.getPCHContainerReader(),
1179 ModuleIndexPath,
1180 &IDs));
1181 ModuleManager->resetForReload();
1182 ModuleManager->loadGlobalIndex();
1183 GlobalIndex = ModuleManager->getGlobalIndex();
1184 }
1186 }
1187 return GlobalIndex;
1188}
1189
1190static void RegisterCxxModules(cling::Interpreter &clingInterp)
1191{
1192 if (!clingInterp.getCI()->getLangOpts().Modules)
1193 return;
1194
1195 // Loading of a module might deserialize.
1196 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1197
1198 // Setup core C++ modules if we have any to setup.
1199
1200 // Load libc and stl first.
1201 // Load vcruntime module for windows
1202#ifdef R__WIN32
1203 LoadModule("vcruntime", clingInterp);
1204 LoadModule("services", clingInterp);
1205#endif
1206
1207#ifdef R__MACOSX
1208 LoadModule("Darwin", clingInterp);
1209#else
1210 LoadModule("libc", clingInterp);
1211#endif
1212 LoadModule("std", clingInterp);
1213
1214 LoadModule("_Builtin_intrinsics", clingInterp);
1215
1216 // Load core modules
1217 // This should be vector in order to be able to pass it to LoadModules
1218 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1219 "ROOT_Config",
1220 "ROOT_Rtypes",
1221 "ROOT_Foundation_Stage1_NoRTTI",
1222 "Core",
1223 "Rint",
1224 "RIO"};
1225
1226 LoadModules(CoreModules, clingInterp);
1227
1228 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1229 if (!IsFromRootCling()) {
1230 std::vector<std::string> CommonModules = {"MathCore"};
1231 LoadModules(CommonModules, clingInterp);
1232
1233 // These modules should not be preloaded but they fix issues.
1234 // FIXME: Hist is not a core module but is very entangled to MathCore and
1235 // causes issues.
1236 std::vector<std::string> FIXMEModules = {"Hist"};
1237 clang::CompilerInstance &CI = *clingInterp.getCI();
1238 clang::Preprocessor &PP = CI.getPreprocessor();
1239 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1240 if (MMap.findModule("RInterface"))
1241 FIXMEModules.push_back("RInterface");
1242
1243 LoadModules(FIXMEModules, clingInterp);
1244
1245 GlobalModuleIndex *GlobalIndex = nullptr;
1246 // Conservatively enable platform by platform.
1247 bool supportedPlatform =
1248#ifdef R__LINUX
1249 true
1250#elif defined(R__MACOSX)
1251 true
1252#else // Windows
1253 false
1254#endif
1255 ;
1256 // Allow forcefully enabling/disabling the GMI.
1257 llvm::Optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1258 if (envUseGMI.hasValue()) {
1259 if (!envUseGMI->empty() && !ROOT::FoundationUtils::CanConvertEnvValueToBool(*envUseGMI))
1260 ::Warning("TCling__RegisterCxxModules",
1261 "Cannot convert '%s' to bool, setting to false!",
1262 envUseGMI->c_str());
1263
1264 bool value = envUseGMI->empty() || ROOT::FoundationUtils::ConvertEnvValueToBool(*envUseGMI);
1265
1266 if (supportedPlatform == value)
1267 ::Warning("TCling__RegisterCxxModules", "Global module index is%sused already!",
1268 (value) ? " " :" not ");
1269 supportedPlatform = value;
1270 }
1271
1272 if (supportedPlatform) {
1273 loadGlobalModuleIndex(clingInterp);
1274 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1275 // We should investigate how to suppress it completely.
1276 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1277 }
1278
1279 llvm::StringSet<> KnownModuleFileNames;
1280 if (GlobalIndex)
1281 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1282
1283 std::vector<std::string> PendingModules;
1284 PendingModules.reserve(256);
1285 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1286 clang::Module *M = I->second;
1287 assert(M);
1288
1289 // We want to load only already created modules.
1290 std::string FullASTFilePath;
1291 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1292 continue;
1293
1294 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1295 continue;
1296
1297 if (M->IsUnimportable)
1298 continue;
1299
1300 if (GlobalIndex)
1301 LoadModule(M->Name, clingInterp);
1302 else {
1303 // FIXME: We may be able to remove those checks as cling::loadModule
1304 // checks if a module was alredy loaded.
1305 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1306 continue; // This is a core module which was already loaded.
1307
1308 // Load system modules now and delay the other modules after we have
1309 // loaded all system ones.
1310 if (M->IsSystem)
1311 LoadModule(M->Name, clingInterp);
1312 else
1313 PendingModules.push_back(M->Name);
1314 }
1315 }
1316 LoadModules(PendingModules, clingInterp);
1317 }
1318
1319 // Check that the gROOT macro was exported by any core module.
1320 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1321
1322 // `ERROR` and `PI` are from loading R related modules, which conflict with
1323 // user's code.
1324 clingInterp.declare(R"CODE(
1325#ifdef PI
1326# undef PI
1327#endif
1328#ifdef ERROR
1329# undef ERROR
1330#endif
1331 )CODE");
1332}
1333
1334static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1335{
1336 std::string PreIncludes;
1337 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1338
1339 // For the list to also include string, we have to include it now.
1340 // rootcling does parts already if needed, e.g. genreflex does not want using
1341 // namespace std.
1342 if (IsFromRootCling()) {
1343 PreIncludes += "#include \"RtypesCore.h\"\n";
1344 } else {
1345 if (!hasCxxModules)
1346 PreIncludes += "#include \"Rtypes.h\"\n";
1347
1348 PreIncludes += gClassDefInterpMacro + "\n"
1349 + gInterpreterClassDef + "\n"
1350 "#undef ClassImp\n"
1351 "#define ClassImp(X);\n";
1352 }
1353 if (!hasCxxModules)
1354 PreIncludes += "#include <string>\n";
1355
1356 // We must include it even when we have modules because it is marked as
1357 // textual in the modulemap due to the nature of the assert header.
1358#ifndef R__WIN32
1359 PreIncludes += "#include <cassert>\n";
1360#endif
1361 PreIncludes += "using namespace std;\n";
1362 clingInterp.declare(PreIncludes);
1363}
1364
1365////////////////////////////////////////////////////////////////////////////////
1366/// Initialize the cling interpreter interface.
1367/// \param name name for TInterpreter
1368/// \param title title for TInterpreter
1369/// \param argv - array of arguments passed to the cling::Interpreter constructor
1370/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1371
1372TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1373: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1377{
1378 fPrompt[0] = 0;
1379 const bool fromRootCling = IsFromRootCling();
1380
1381 fCxxModulesEnabled = false;
1382#ifdef R__USE_CXXMODULES
1383 fCxxModulesEnabled = true;
1384#endif
1385
1386 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1387
1388 fTemporaries = new std::vector<cling::Value>();
1389
1390 std::vector<std::string> clingArgsStorage;
1391 clingArgsStorage.push_back("cling4root");
1392 for (const char* const* arg = argv; *arg; ++arg)
1393 clingArgsStorage.push_back(*arg);
1394
1395 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1396 if (!fromRootCling) {
1398
1399 // Add -I early so ASTReader can find the headers.
1400 std::string interpInclude(TROOT::GetEtcDir().Data());
1401 clingArgsStorage.push_back("-I" + interpInclude);
1402
1403 // Add include path to etc/cling.
1404 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1405
1406 // Add include path to etc/cling.
1407 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1408
1409 // Add the root include directory and etc/ to list searched by default.
1410 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1411
1412 // Add the current path to the include path
1413 // TCling::AddIncludePath(".");
1414
1415 // Attach the PCH (unless we have C++ modules enabled which provide the
1416 // same functionality).
1417 if (!fCxxModulesEnabled) {
1418 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1419 if (gSystem->Getenv("ROOT_PCH")) {
1420 pchFilename = gSystem->Getenv("ROOT_PCH");
1421 }
1422
1423 clingArgsStorage.push_back("-include-pch");
1424 clingArgsStorage.push_back(pchFilename);
1425 }
1426
1427 clingArgsStorage.push_back("-Wno-undefined-inline");
1428 clingArgsStorage.push_back("-fsigned-char");
1429 // The -O1 optimization flag has nasty side effects on Windows (32 bit)
1430 // See the GitHub issues #9809 and #9944
1431#if !defined(_MSC_VER) || defined(_WIN64)
1432 clingArgsStorage.push_back("-O1");
1433 // Disable optimized register allocation which is turned on automatically
1434 // by -O1, but seems to require -O2 to not explode in run time.
1435 clingArgsStorage.push_back("-mllvm");
1436 clingArgsStorage.push_back("-optimize-regalloc=0");
1437#endif
1438 }
1439
1440 // Process externally passed arguments if present.
1441 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1442 if (EnvOpt.hasValue()) {
1443 StringRef Env(*EnvOpt);
1444 while (!Env.empty()) {
1445 StringRef Arg;
1446 std::tie(Arg, Env) = Env.split(' ');
1447 clingArgsStorage.push_back(Arg.str());
1448 }
1449 }
1450
1451 auto GetEnvVarPath = [](const std::string &EnvVar,
1452 std::vector<std::string> &Paths) {
1453 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1454 if (EnvOpt.hasValue()) {
1455 StringRef Env(*EnvOpt);
1456 while (!Env.empty()) {
1457 StringRef Arg;
1458 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1459 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1460 Paths.push_back(Arg.str());
1461 }
1462 }
1463 };
1464
1465 if (fCxxModulesEnabled) {
1466 std::vector<std::string> Paths;
1467 // ROOT usually knows better where its libraries are. This way we can
1468 // discover modules without having to should thisroot.sh and should fix
1469 // gnuinstall.
1470#ifdef R__WIN32
1471 Paths.push_back(TROOT::GetBinDir().Data());
1472#else
1473 Paths.push_back(TROOT::GetLibDir().Data());
1474#endif
1475 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1476 std::string EnvVarPath;
1477 for (const std::string& P : Paths)
1479 // FIXME: We should make cling -fprebuilt-module-path work.
1480 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1481 }
1482
1483 // FIXME: This only will enable frontend timing reports.
1484 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1485 if (EnvOpt.hasValue())
1486 clingArgsStorage.push_back("-ftime-report");
1487
1488 // Add the overlay file. Note that we cannot factor it out for both root
1489 // and rootcling because rootcling activates modules only if -cxxmodule
1490 // flag is passed.
1491 if (fCxxModulesEnabled && !fromRootCling) {
1492 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1493 std::vector<std::string> ModuleMaps;
1494 //std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "module.modulemap";
1495 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1496 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1497 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1498
1499 std::string cwd = gSystem->WorkingDirectory();
1500 // Give highest precedence of the modulemap in the cwd if any.
1501 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1502 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1503
1504 for (const std::string& M : ModuleMaps)
1505 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1506
1507 std::string ModulesCachePath;
1508 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1509 if (EnvOpt.hasValue()){
1510 StringRef Env(*EnvOpt);
1511 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1512 ModulesCachePath = Env.str();
1513 } else {
1514 ModulesCachePath = TROOT::GetLibDir();
1515 }
1516
1517 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1518 }
1519
1520 std::vector<const char*> interpArgs;
1521 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1522 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1523 interpArgs.push_back(iArg->c_str());
1524
1525 // Activate C++ modules support. If we are running within rootcling, it's up
1526 // to rootcling to set this flag depending on whether it wants to produce
1527 // C++ modules.
1528 TString vfsArg;
1529 if (fCxxModulesEnabled) {
1530 if (!fromRootCling) {
1531 // We only set this flag, rest is done by the CIFactory.
1532 interpArgs.push_back("-fmodules");
1533 interpArgs.push_back("-fno-implicit-module-maps");
1534 // We should never build modules during runtime, so let's enable the
1535 // module build remarks from clang to make it easier to spot when we do
1536 // this by accident.
1537 interpArgs.push_back("-Rmodule-build");
1538 }
1539 // ROOT implements its AutoLoading upon module's link directives. We
1540 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1541 // facilities use the link directive to dynamically load the relevant
1542 // library. So, we need to suppress clang's default autolink behavior.
1543 interpArgs.push_back("-fno-autolink");
1544 }
1545
1546#ifdef R__FAST_MATH
1547 // Same setting as in rootcling_impl.cxx.
1548 interpArgs.push_back("-ffast-math");
1549#endif
1550
1551 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1552 // Add statically injected extra arguments, usually coming from rootcling.
1553 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1554 extraArgs && *extraArgs; ++extraArgs) {
1555 if (!strcmp(*extraArgs, "-resource-dir")) {
1556 // Take the next arg as the llvm resource directory.
1557 llvmResourceDir = *(++extraArgs);
1558 } else {
1559 interpArgs.push_back(*extraArgs);
1560 }
1561 }
1562
1563 std::vector<std::string> _empty;
1564 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1565 for (const auto &arg: args)
1566 interpArgs.emplace_back(arg.c_str());
1567
1568 // Add the Rdict module file extension.
1569 cling::Interpreter::ModuleFileExtensions extensions;
1570 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1571 if (!EnvOpt.hasValue())
1572 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1573
1574 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1575 &(interpArgs[0]),
1576 llvmResourceDir, extensions,
1577 interpLibHandle);
1578
1579 // Don't check whether modules' files exist.
1580 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1581 DisableValidationForModuleKind::All;
1582
1583 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1584 // to disable spell checking.
1585 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1586
1587 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1588 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1589 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1590 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1591
1592 // We need stream that doesn't close its file descriptor, thus we are not
1593 // using llvm::outs. Keeping file descriptor open we will be able to use
1594 // the results in pipes (Savannah #99234).
1595 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1596 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1597
1600
1601 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1608
1609 // Disallow auto-parsing in rootcling
1610 fIsAutoParsingSuspended = fromRootCling;
1611
1612 ResetAll();
1613
1614 // Enable dynamic lookup
1615 if (!fromRootCling) {
1616 fInterpreter->enableDynamicLookup();
1617 }
1618
1619 // Enable ClinG's DefinitionShadower for ROOT.
1620 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1621 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1622 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1623 // FIXME: We should probably switch to the default printing policy setting
1624 // after adjusting tons of reference files.
1625 Policy.SplitTemplateClosers = true;
1626 // Keep default templare arguments, required for dictionary generation.
1627 Policy.SuppressDefaultTemplateArgs = false;
1628
1629
1630 // Attach cling callbacks last; they might need TROOT::fInterpreter
1631 // and should thus not be triggered during the equivalent of
1632 // TROOT::fInterpreter = new TCling;
1633 std::unique_ptr<TClingCallbacks>
1634 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1635 fClingCallbacks = clingCallbacks.get();
1637 fInterpreter->setCallbacks(std::move(clingCallbacks));
1638
1639 if (!fromRootCling) {
1640 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1641 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1642 // e.g. because of an RPATH build.
1643 DLM.addSearchPath(TROOT::GetLibDir().Data(), /*isUser=*/true,
1644 /*prepend=*/true);
1645 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1646 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1647 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1648 };
1649 // Initialize the dyld for AutoloadLibraryGenerator.
1650 DLM.initializeDyld(ShouldPermanentlyIgnore);
1651 }
1652}
1653
1654
1655////////////////////////////////////////////////////////////////////////////////
1656/// Destroy the interpreter interface.
1657
1659{
1660 // ROOT's atexit functions require the interepreter to be available.
1661 // Run them before shutting down.
1662 if (!IsFromRootCling())
1663 GetInterpreterImpl()->runAtExitFuncs();
1664 fIsShuttingDown = true;
1665 delete fMapfile;
1666 delete fRootmapFiles;
1667 delete fTemporaries;
1668 delete fNormalizedCtxt;
1669 delete fLookupHelper;
1670 gCling = 0;
1671}
1672
1673////////////////////////////////////////////////////////////////////////////////
1674/// Initialize the interpreter, once TROOT::fInterpreter is set.
1675
1677{
1679
1680 // We are set up. Enable ROOT's AutoLoading.
1681 if (IsFromRootCling())
1682 return;
1683
1684 // Read the rules before enabling the auto loading to not inadvertently
1685 // load the libraries for the classes concerned even-though the user is
1686 // *not* using them.
1687 // Note this call must happen before the first call to LoadLibraryMap.
1688 assert(GetRootMapFiles() == 0 && "Must be called before LoadLibraryMap!");
1689 TClass::ReadRules(); // Read the default customization rules ...
1690
1692 SetClassAutoLoading(true);
1693}
1694
1696{
1697 fIsShuttingDown = true;
1698 ResetGlobals();
1699}
1700
1701////////////////////////////////////////////////////////////////////////////////
1702/// Helper to initialize TVirtualStreamerInfo's factor early.
1703/// Use static initialization to insure only one TStreamerInfo is created.
1705{
1706 // Use lambda since SetFactory return void.
1707 auto setFactory = []() {
1709 return kTRUE;
1710 };
1711 static bool doneFactory = setFactory();
1712 return doneFactory; // avoid unused variable warning.
1713}
1714
1715////////////////////////////////////////////////////////////////////////////////
1716/// Register Rdict data for future loading by LoadPCM;
1717
1718void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1719{
1720 if (IsFromRootCling())
1721 return;
1722
1723 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1724 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1725 return;
1726 }
1727
1728 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1729 // a link to a non-existent file.
1730 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1731}
1732
1733////////////////////////////////////////////////////////////////////////////////
1734/// Tries to load a PCM from TFile; returns true on success.
1735
1737{
1738 auto listOfKeys = pcmFile.GetListOfKeys();
1739
1740 // This is an empty pcm
1741 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1742 ((listOfKeys->GetSize() == 1) && // only one, and
1743 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1744 ))) {
1745 return;
1746 }
1747
1748 TObjArray *protoClasses;
1749 if (gDebug > 1)
1750 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1751
1752 TObjArray *enums;
1753 pcmFile.GetObject("__Enums", enums);
1754 if (enums) {
1755 // Cache the pointers
1756 auto listOfGlobals = gROOT->GetListOfGlobals();
1757 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1758 // Loop on enums and then on enum constants
1759 for (auto selEnum : *enums) {
1760 const char *enumScope = selEnum->GetTitle();
1761 const char *enumName = selEnum->GetName();
1762 if (strcmp(enumScope, "") == 0) {
1763 // This is a global enum and is added to the
1764 // list of enums and its constants to the list of globals
1765 if (!listOfEnums->THashList::FindObject(enumName)) {
1766 ((TEnum *)selEnum)->SetClass(nullptr);
1767 listOfEnums->Add(selEnum);
1768 }
1769 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1770 if (!listOfGlobals->FindObject(enumConstant)) {
1771 listOfGlobals->Add(enumConstant);
1772 }
1773 }
1774 } else {
1775 // This enum is in a namespace. A TClass entry is bootstrapped if
1776 // none exists yet and the enum is added to it
1777 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1778 if (!nsTClassEntry) {
1779 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1780 }
1781 auto listOfEnums = nsTClassEntry->fEnums.load();
1782 if (!listOfEnums) {
1783 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1784 // For this case, the list will be immutable once constructed
1785 // (i.e. in this case, by the end of this routine).
1786 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1787 } else {
1788 // namespaces can have enums added to them
1789 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1790 }
1791 }
1792 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1793 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1794 listOfEnums->Add(selEnum);
1795 }
1796 }
1797 }
1798 enums->Clear();
1799 delete enums;
1800 }
1801
1802 pcmFile.GetObject("__ProtoClasses", protoClasses);
1803
1804 if (protoClasses) {
1805 for (auto obj : *protoClasses) {
1806 TProtoClass *proto = (TProtoClass *)obj;
1808 }
1809 // Now that all TClass-es know how to set them up we can update
1810 // existing TClasses, which might cause the creation of e.g. TBaseClass
1811 // objects which in turn requires the creation of TClasses, that could
1812 // come from the PCH, but maybe later in the loop. Instead of resolving
1813 // a dependency graph the addition to the TClassTable above allows us
1814 // to create these dependent TClasses as needed below.
1815 for (auto proto : *protoClasses) {
1816 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1817 // We have an existing TClass object. It might be emulated
1818 // or interpreted; we now have more information available.
1819 // Make that available.
1820 if (existingCl->GetState() != TClass::kHasTClassInit) {
1821 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1822 if (!dict) {
1823 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1824 } else {
1825 // This will replace the existing TClass.
1826 TClass *ncl = (*dict)();
1827 if (ncl)
1828 ncl->PostLoadCheck();
1829 }
1830 }
1831 }
1832 }
1833
1834 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1835 delete protoClasses;
1836 }
1837
1838 TObjArray *dataTypes;
1839 pcmFile.GetObject("__Typedefs", dataTypes);
1840 if (dataTypes) {
1841 for (auto typedf : *dataTypes)
1842 gROOT->GetListOfTypes()->Add(typedf);
1843 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1844 delete dataTypes;
1845 }
1846}
1847
1848////////////////////////////////////////////////////////////////////////////////
1849/// Tries to load a rdict PCM, issues diagnostics if it fails.
1850
1851void TCling::LoadPCM(std::string pcmFileNameFullPath)
1852{
1853 SuspendAutoLoadingRAII autoloadOff(this);
1854 SuspendAutoParsing autoparseOff(this);
1855 assert(!pcmFileNameFullPath.empty());
1856 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1857
1858 // Easier to work with the ROOT interfaces.
1859 TString pcmFileName = pcmFileNameFullPath;
1860
1861 // Prevent the ROOT-PCMs hitting this during auto-load during
1862 // JITting - which will cause recursive compilation.
1863 // Avoid to call the plugin manager at all.
1865
1867 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1868 if (gDebug > 5) {
1869 gDebug -= 5;
1870 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1871 } else {
1872 gDebug = 0;
1873 }
1874
1875 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1876 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1877
1878 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1879 if (pendingRdict != fPendingRdicts.end()) {
1880 llvm::StringRef pcmContent = pendingRdict->second;
1881 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1882 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1883 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1884
1885 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1886 LoadPCMImpl(pcmMemFile);
1887 // Currently the module file are never unloaded (even if the library is
1888 // unloaded) and, of course, never reloaded.
1889 // Consequently, we must NOT remove the `pendingRdict` from the list
1890 // of pending dictionary, otherwise if a library is unloaded and then
1891 // reload we will be unable to update properly the TClass object
1892 // (because we wont be able to load the rootpcm file by executing the
1893 // above lines)
1894
1895 return;
1896 }
1897
1898 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1899 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1900 pcmFileNameFullPath.data());
1901 if (!fPendingRdicts.empty())
1902 for (const auto &rdict : fPendingRdicts)
1903 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1904 rdict.first.c_str());
1905 return;
1906 }
1907
1908 if (!gROOT->IsRootFile(pcmFileName)) {
1909 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1910 return;
1911 }
1912 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1913 LoadPCMImpl(pcmFile);
1914}
1915
1916//______________________________________________________________________________
1917
1918namespace {
1919 using namespace clang;
1920
1921 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1922 // This class is to be considered an helper for autoparsing.
1923 // It visits the AST and marks all classes (in all of their redeclarations)
1924 // with the setHasExternalLexicalStorage method.
1925 public:
1926 bool VisitRecordDecl(clang::RecordDecl* rcd){
1927 if (gDebug > 2)
1928 Info("ExtLexicalStorageAdder",
1929 "Adding external lexical storage to class %s",
1930 rcd->getNameAsString().c_str());
1931 auto reDeclPtr = rcd->getMostRecentDecl();
1932 do {
1933 reDeclPtr->setHasExternalLexicalStorage();
1934 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1935
1936 return false;
1937 }
1938 };
1939
1940
1941}
1942
1943////////////////////////////////////////////////////////////////////////////////
1944///\returns true if the module map was loaded, false on error or if the map was
1945/// already loaded.
1946bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1947 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1948{
1949 assert(llvm::sys::path::is_absolute(FullPath));
1950 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1951 FileManager &FM = PP.getFileManager();
1952 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1953 // We should look for modulemap files there too.
1954 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1955 HeaderSearch &HS = PP.getHeaderSearchInfo();
1956 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1957 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1958 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1959 if (!pathExists)
1960 HSOpts.AddPrebuiltModulePath(FullPath);
1961 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1962 // because its internal call to getFile has CacheFailure set to true.
1963 // In our case, modulemaps can appear any time due to ACLiC.
1964 // Code copied from HS.lookupModuleMapFile.
1965 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1966 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1967 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1968 /*CacheFailure*/ false)) {
1969 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1970 return true;
1971 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1972 }
1973 }
1974 return false;
1975}
1976
1977////////////////////////////////////////////////////////////////////////////////
1978/// List of dicts that have the PCM information already in the PCH.
1979static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1980 "libRint",
1981 "libThread",
1982 "libRIO",
1983 "libImt",
1984 "libMultiProc",
1985 "libcomplexDict",
1986 "libdequeDict",
1987 "liblistDict",
1988 "libforward_listDict",
1989 "libvectorDict",
1990 "libmapDict",
1991 "libmultimap2Dict",
1992 "libmap2Dict",
1993 "libmultimapDict",
1994 "libsetDict",
1995 "libmultisetDict",
1996 "libunordered_setDict",
1997 "libunordered_multisetDict",
1998 "libunordered_mapDict",
1999 "libunordered_multimapDict",
2000 "libvalarrayDict",
2001 "G__GenVector32",
2002 "G__Smatrix32"};
2003
2004static void PrintDlError(const char *dyLibName, const char *modulename)
2005{
2006#ifdef R__WIN32
2007 char dyLibError[1000];
2008 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2009 dyLibError, sizeof(dyLibError), NULL);
2010#else
2011 const char *dyLibError = dlerror();
2012#endif
2013 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2014 (dyLibError) ? dyLibError : "");
2015}
2016
2017////////////////////////////////////////////////////////////////////////////////
2018// Update all the TClass registered in fClassesToUpdate
2019
2021{
2022 while (!fClassesToUpdate.empty()) {
2023 TClass *oldcl = fClassesToUpdate.back().first;
2024 // If somehow the TClass has already been loaded (maybe it was registered several time),
2025 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2026 // maybe even kForwardDeclared and needs to replaced.
2027 if (oldcl->GetState() != TClass::kHasTClassInit) {
2028 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2029 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2030 fClassesToUpdate.pop_back();
2031 // Calling func could manipulate the list so, let maintain the list
2032 // then call the dictionary function.
2033 TClass *ncl = dict();
2034 if (ncl) ncl->PostLoadCheck();
2035 } else {
2036 fClassesToUpdate.pop_back();
2037 }
2038 }
2039}
2040////////////////////////////////////////////////////////////////////////////////
2041/// Inject the module named "modulename" into cling; load all headers.
2042/// headers is a 0-terminated array of header files to `#include` after
2043/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2044/// entries (or %PATH% on Windows).
2045/// This function gets called by the static initialization of dictionary
2046/// libraries.
2047/// The payload code is injected "as is" in the interpreter.
2048/// The value of 'triggerFunc' is used to find the shared library location.
2049
2050void TCling::RegisterModule(const char* modulename,
2051 const char** headers,
2052 const char** includePaths,
2053 const char* payloadCode,
2054 const char* fwdDeclsCode,
2055 void (*triggerFunc)(),
2056 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2057 const char** classesHeaders,
2058 Bool_t lateRegistration /*=false*/,
2059 Bool_t hasCxxModule /*=false*/)
2060{
2061 const bool fromRootCling = IsFromRootCling();
2062 // We need the dictionary initialization but we don't want to inject the
2063 // declarations into the interpreter, except for those we really need for
2064 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2065 if (fromRootCling) return;
2066
2067 // When we cannot provide a module for the library we should enable header
2068 // parsing. This 'mixed' mode ensures gradual migration to modules.
2069 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2070 fHeaderParsingOnDemand = !hasCxxModule;
2071
2072 // Treat Aclic Libs in a special way. Do not delay the parsing.
2073 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2074 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2075 if (hasHeaderParsingOnDemand && isACLiC) {
2076 if (gDebug>1)
2077 Info("TCling::RegisterModule",
2078 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2079 hasHeaderParsingOnDemand = false;
2080 }
2081
2082
2083 // Make sure we relookup symbols that were search for before we loaded
2084 // their autoparse information. We could be more subtil and remove only
2085 // the failed one or only the one in this module, but for now this is
2086 // better than nothing.
2087 fLookedUpClasses.clear();
2088
2089 // Make sure we do not set off AutoLoading or autoparsing during the
2090 // module registration!
2091 SuspendAutoLoadingRAII autoLoadOff(this);
2092
2093 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2094 TCling::AddIncludePath(*inclPath);
2095 }
2096 cling::Transaction* T = 0;
2097 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2098 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2099 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2100 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2101 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2102 assert(cling::Interpreter::kSuccess == compRes &&
2103 "A fwd declaration could not be compiled");
2104 if (compRes!=cling::Interpreter::kSuccess){
2105 Warning("TCling::RegisterModule",
2106 "Problems in declaring string '%s' were encountered.",
2107 fwdDecl.c_str()) ;
2108 continue;
2109 }
2110
2111 // Drill through namespaces recursively until the template is found
2112 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2113 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2114 }
2115
2116 }
2117
2118 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2119 // This is used to give Sema the same view on ACLiC'ed files (which
2120 // are then #included through the dictionary) as rootcling had.
2121 TString code = gNonInterpreterClassDef;
2122 if (payloadCode)
2123 code += payloadCode;
2124
2125 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2126 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2127
2128 if (dyLibName.empty()) {
2129 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2130 return;
2131 }
2132
2133 // The triggerFunc may not be in a shared object but in an executable.
2134 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2135
2136 bool wasDlopened = false;
2137
2138 // If this call happens after dlopen has finished (i.e. late registration)
2139 // there is no need to dlopen the library recursively. See ROOT-8437 where
2140 // the dyLibName would correspond to the binary.
2141 if (!lateRegistration) {
2142
2143 if (isSharedLib) {
2144 // We need to open the dictionary shared library, to resolve symbols
2145 // requested by the JIT from it: as the library is currently being dlopen'ed,
2146 // its symbols are not yet reachable from the process.
2147 // Recursive dlopen seems to work just fine.
2148 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2149 if (dyLibHandle) {
2150 fRegisterModuleDyLibs.push_back(dyLibHandle);
2151 wasDlopened = true;
2152 } else {
2153 PrintDlError(dyLibName.c_str(), modulename);
2154 }
2155 }
2156 } // if (!lateRegistration)
2157
2158 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2159 // We now parse the forward declarations. All the classes are then modified
2160 // in order for them to have an external lexical storage.
2161 std::string fwdDeclsCodeLessEnums;
2162 {
2163 // Search for enum forward decls and only declare them if no
2164 // declaration exists yet.
2165 std::string fwdDeclsLine;
2166 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2167 std::vector<std::string> scopes;
2168 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2169 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2170 // We check if the line contains a fwd declaration of an enum
2171 if (enumPos != std::string::npos) {
2172 // We clear the scopes which we may have carried from a previous iteration
2173 scopes.clear();
2174 // We check if the enum is not in a scope. If yes, save its name
2175 // and the names of the enclosing scopes.
2176 if (enumPos != 0) {
2177 // it's enclosed in namespaces. We need to understand what they are
2178 auto nsPos = fwdDeclsLine.find("namespace");
2179 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2180 while (nsPos < enumPos && nsPos != std::string::npos) {
2181 // we have a namespace, let's put it in the collection of scopes
2182 const auto nsNameStart = nsPos + 10;
2183 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2184 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2185 scopes.push_back(nsName);
2186 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2187 }
2188 }
2189 clang::DeclContext* DC = 0;
2190 for (auto &&aScope: scopes) {
2191 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2192 if (!DC) {
2193 // No decl context means we have to fwd declare the enum.
2194 break;
2195 }
2196 }
2197 if (scopes.empty() || DC) {
2198 // We know the scope; let's look for the enum. For that, look
2199 // for the *last* closing parentheses of an attribute because
2200 // there can be multiple.
2201 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2202 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2203 posEnumName += 5; // skip "\"))) "
2204 while (isspace(fwdDeclsLine[posEnumName]))
2205 ++posEnumName;
2206 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2207 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2208 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2209 --posEnumNameEnd;
2210 // posEnumNameEnd now points to the last character of the name.
2211
2212 std::string enumName = fwdDeclsLine.substr(posEnumName,
2213 posEnumNameEnd - posEnumName + 1);
2214
2215 if (clang::NamedDecl* enumDecl
2216 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2217 enumName.c_str(), DC)) {
2218 // We have an existing enum decl (forward or definition);
2219 // skip this.
2220 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2221 (void)enumDecl;
2222 continue;
2223 }
2224 }
2225 }
2226
2227 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2228 }
2229 }
2230
2231 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2232 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2233 assert(cling::Interpreter::kSuccess == compRes &&
2234 "The forward declarations could not be compiled");
2235 if (compRes!=cling::Interpreter::kSuccess){
2236 Warning("TCling::RegisterModule",
2237 "Problems in compiling forward declarations for module %s: '%s'",
2238 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2239 }
2240 else if (T){
2241 // Loop over all decls in the transaction and go through them all
2242 // to mark them properly.
2243 // In order to do that, we first iterate over all the DelayedCallInfos
2244 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2245 // contained in the DelayedCallInfos. For each decl, we traverse.
2246 ExtLexicalStorageAdder elsa;
2247 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2248 cling::Transaction::DelayCallInfo& dci = *dciIt;
2249 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2250 clang::Decl* declPtr = *dit;
2251 elsa.TraverseDecl(declPtr);
2252 }
2253 }
2254 }
2255 }
2256
2257 // Now we register all the headers necessary for the class
2258 // Typical format of the array:
2259 // {"A", "classes.h", "@",
2260 // "vector<A>", "vector", "@",
2261 // "myClass", payloadCode, "@",
2262 // nullptr};
2263
2264 std::string temp;
2265 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2266 temp=*classesHeader;
2267
2268 size_t theTemplateHash = 0;
2269 bool addTemplate = false;
2270 size_t posTemplate = temp.find('<');
2271 if (posTemplate != std::string::npos) {
2272 // Add an entry for the template itself.
2273 std::string templateName = temp.substr(0, posTemplate);
2274 theTemplateHash = fStringHashFunction(templateName);
2275 addTemplate = true;
2276 }
2277 size_t theHash = fStringHashFunction(temp);
2278 classesHeader++;
2279 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2280 // This is done in order to distinguish headers from files and from the payloadCode
2281 if (payloadCode == *classesHeader_inner ){
2282 fPayloads.insert(theHash);
2283 if (addTemplate) fPayloads.insert(theTemplateHash);
2284 }
2285 if (gDebug > 2)
2286 Info("TCling::RegisterModule",
2287 "Adding a header for %s", temp.c_str());
2288 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2289 if (addTemplate) {
2290 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2291 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2292 }
2293 addTemplate = false;
2294 }
2295 }
2296 }
2297 }
2298
2299 clang::Sema &TheSema = fInterpreter->getSema();
2300
2301 bool ModuleWasSuccessfullyLoaded = false;
2302 if (hasCxxModule) {
2303 std::string ModuleName = modulename;
2304 if (llvm::StringRef(modulename).startswith("lib"))
2305 ModuleName = llvm::StringRef(modulename).substr(3).str();
2306
2307 // In case we are directly loading the library via gSystem->Load() without
2308 // specifying the relevant include paths we should try loading the
2309 // modulemap next to the library location.
2310 clang::Preprocessor &PP = TheSema.getPreprocessor();
2311 std::string ModuleMapName;
2312 if (isACLiC)
2313 ModuleMapName = ModuleName + ".modulemap";
2314 else
2315 ModuleMapName = "module.modulemap";
2316 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2317 ModuleMapName);
2318
2319 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2320 // modules such as GenVector32 because it needs to fall back to GenVector.
2321 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2322 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2323 if (!ModuleWasSuccessfullyLoaded) {
2324 // Only report if we found the module in the modulemap.
2325 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2326 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2327 if (moduleMap.findModule(ModuleName))
2328 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2329 }
2330 }
2331
2332 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2333 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2334 // The path dyLibName might not be absolute. This can happen if dyLibName
2335 // is linked to an executable in the same folder.
2336 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2337 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2338 llvm::sys::path::append(pcmFileNameFullPath,
2340 LoadPCM(pcmFileNameFullPath.str().str());
2341 }
2342
2343 { // scope within which diagnostics are de-activated
2344 // For now we disable diagnostics because we saw them already at
2345 // dictionary generation time. That won't be an issue with the PCMs.
2346
2347 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2348
2349#if defined(R__MUST_REVISIT)
2350#if R__MUST_REVISIT(6,2)
2351 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2352#endif
2353#endif
2354
2355 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2356 SuspendAutoParsing autoParseRaii(this);
2357
2358 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2359 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2360 if (isACLiC) {
2361 // Register an unload point.
2362 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2363 }
2364
2365 assert(cling::Interpreter::kSuccess == compRes &&
2366 "Payload code of a dictionary could not be parsed correctly.");
2367 if (compRes!=cling::Interpreter::kSuccess) {
2368 Warning("TCling::RegisterModule",
2369 "Problems declaring payload for module %s.", modulename) ;
2370 }
2371 }
2372 }
2373
2374 // Now that all the header have been registered/compiled, let's
2375 // make sure to 'reset' the TClass that have a class init in this module
2376 // but already had their type information available (using information/header
2377 // loaded from other modules or from class rules or from opening a TFile
2378 // or from loading header in a way that did not provoke the loading of
2379 // the library we just loaded).
2381
2382 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2383 // __ROOTCLING__ might be pulled in through PCH
2384 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2385 "#undef __ROOTCLING__\n"
2386 + gInterpreterClassDef +
2387 "#endif");
2388 }
2389
2390 if (wasDlopened) {
2391 assert(isSharedLib);
2392 void* dyLibHandle = fRegisterModuleDyLibs.back();
2393 fRegisterModuleDyLibs.pop_back();
2394 dlclose(dyLibHandle);
2395 }
2396}
2397
2399 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2400 ASTContext &C = CI.getASTContext();
2401
2402 // Do not do anything if we have no global module index.
2403 // FIXME: This is mostly to real with false positives in the TTabCom
2404 // interface for non-modules.
2405 if (!fCxxModulesEnabled)
2406 return;
2407
2408 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2409 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2410 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2411 std::string I = Ident.str();
2412 if (!Idents.Contains(I.data()))
2413 Idents.Add(new TObjString(I.c_str()));
2414 }
2415 }
2416}
2417
2418
2419////////////////////////////////////////////////////////////////////////////////
2420/// Register classes that already existed prior to their dictionary loading
2421/// and that already had a ClassInfo (and thus would not be refresh via
2422/// UpdateClassInfo.
2423
2425{
2426 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2427}
2428
2429////////////////////////////////////////////////////////////////////////////////
2430/// If the dictionary is loaded, we can remove the class from the list
2431/// (otherwise the class might be loaded twice).
2432
2434{
2435 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2436 iterator stop = fClassesToUpdate.end();
2437 for(iterator i = fClassesToUpdate.begin();
2438 i != stop;
2439 ++i)
2440 {
2441 if ( i->first == oldcl ) {
2442 fClassesToUpdate.erase(i);
2443 return;
2444 }
2445 }
2446}
2447
2448
2449////////////////////////////////////////////////////////////////////////////////
2450/// Let cling process a command line.
2451///
2452/// If the command is executed and the error is 0, then the return value
2453/// is the int value corresponding to the result of the executed command
2454/// (float and double return values will be truncated).
2455///
2456
2457// Method for handling the interpreter exceptions.
2458// the MetaProcessor is passing in as argument to teh function, because
2459// cling::Interpreter::CompilationResult is a nested class and it cannot be
2460// forward declared, thus this method cannot be a static member function
2461// of TCling.
2462
2463static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2464 const char* input_line,
2465 cling::Interpreter::CompilationResult& compRes,
2466 cling::Value* result)
2467{
2468 try {
2469 return metaProcessor->process(input_line, compRes, result);
2470 }
2471 catch (cling::InterpreterException& ex)
2472 {
2473 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2474 ex.diagnose();
2475 compRes = cling::Interpreter::kFailure;
2476 }
2477 return 0;
2478}
2479
2480////////////////////////////////////////////////////////////////////////////////
2481
2482bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2483{
2484 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2485 ie->diagnose();
2486 return true;
2487 }
2488 return false;
2489}
2490
2491////////////////////////////////////////////////////////////////////////////////
2492
2494{
2495 // Copy the passed line, it comes from a static buffer in TApplication
2496 // which can be reentered through the Cling evaluation routines,
2497 // which would overwrite the static buffer and we would forget what we
2498 // were doing.
2499 //
2500 TString sLine(line);
2501 if (strstr(line,fantomline)) {
2502 // End-Of-Line action
2503 // See the comment (copied from above):
2504 // It is a "fantom" method to synchronize user keyboard input
2505 // and ROOT prompt line (for WIN32)
2506 // and is implemented by
2507 if (gApplication) {
2508 if (gApplication->IsCmdThread()) {
2510 gROOT->SetLineIsProcessing();
2511
2513
2514 gROOT->SetLineHasBeenProcessed();
2515 }
2516 }
2517 return 0;
2518 }
2519
2521 gGlobalMutex->Lock();
2522 if (!gInterpreterMutex)
2525 }
2527 gROOT->SetLineIsProcessing();
2528
2529 struct InterpreterFlagsRAII {
2530 cling::Interpreter* fInterpreter;
2531 bool fWasDynamicLookupEnabled;
2532
2533 InterpreterFlagsRAII(cling::Interpreter* interp):
2534 fInterpreter(interp),
2535 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2536 {
2537 fInterpreter->enableDynamicLookup(true);
2538 }
2539 ~InterpreterFlagsRAII() {
2540 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2541 gROOT->SetLineHasBeenProcessed();
2542 }
2543 } interpreterFlagsRAII(GetInterpreterImpl());
2544
2545 // A non-zero returned value means the given line was
2546 // not a complete statement.
2547 int indent = 0;
2548 // This will hold the resulting value of the evaluation the given line.
2549 cling::Value result;
2550 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2551 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2552 !strncmp(sLine.Data(), ".X", 2)) {
2553 // If there was a trailing "+", then CINT compiled the code above,
2554 // and we will need to strip the "+" before passing the line to cling.
2555 TString mod_line(sLine);
2556 TString aclicMode;
2557 TString arguments;
2558 TString io;
2559 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2560 aclicMode, arguments, io);
2561 if (aclicMode.Length()) {
2562 // Remove the leading '+'
2563 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2564 aclicMode[0]='k'; // We always want to keep the .so around.
2565 if (aclicMode[1]=='+') {
2566 // We have a 2nd +
2567 aclicMode[1]='f'; // We want to force the recompilation.
2568 }
2569 if (!gSystem->CompileMacro(fname,aclicMode)) {
2570 // ACLiC failed.
2571 compRes = cling::Interpreter::kFailure;
2572 } else {
2573 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2574 // if execution was requested.
2575
2576 if (arguments.Length()==0) {
2577 arguments = "()";
2578 }
2579 // We need to remove the extension.
2580 Ssiz_t ext = fname.Last('.');
2581 if (ext != kNPOS) {
2582 fname.Remove(ext);
2583 }
2584 const char *function = gSystem->BaseName(fname);
2585 mod_line = function + arguments + io;
2587 }
2588 }
2589 } else {
2590 // not ACLiC
2591 size_t unnamedMacroOpenCurly;
2592 {
2593 std::string code;
2594 std::string codeline;
2595 // Windows requires std::ifstream::binary to properly handle
2596 // CRLF and LF line endings
2597 std::ifstream in(fname, std::ifstream::binary);
2598 while (in) {
2599 std::getline(in, codeline);
2600 code += codeline + "\n";
2601 }
2602 unnamedMacroOpenCurly
2603 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2604 }
2605
2606 fCurExecutingMacros.push_back(fname);
2607 if (unnamedMacroOpenCurly != std::string::npos) {
2608 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2609 unnamedMacroOpenCurly);
2610 } else {
2611 // No DynLookup for .x, .L of named macros.
2612 fInterpreter->enableDynamicLookup(false);
2614 }
2615 fCurExecutingMacros.pop_back();
2616 }
2617 } // .L / .X / .x
2618 else {
2619 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2620 // explicitly ignore .autodict without having to support it
2621 // in cling.
2622
2623 // Turn off autoparsing if this is an include directive
2624 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2625 if (isInclusionDirective) {
2626 SuspendAutoParsing autoParseRaii(this);
2628 } else {
2630 }
2631 }
2632 }
2633 if (result.isValid())
2635 if (indent) {
2636 if (error)
2637 *error = kProcessing;
2638 return 0;
2639 }
2640 if (error) {
2641 switch (compRes) {
2642 case cling::Interpreter::kSuccess: *error = kNoError; break;
2643 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2644 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2645 }
2646 }
2647 if (compRes == cling::Interpreter::kSuccess
2648 && result.isValid()
2649 && !result.isVoid())
2650 {
2651 return result.simplisticCastAs<Longptr_t>();
2652 }
2653 return 0;
2654}
2655
2656////////////////////////////////////////////////////////////////////////////////
2657/// No-op; see TRint instead.
2658
2660{
2661}
2662
2663////////////////////////////////////////////////////////////////////////////////
2664/// \brief Add a directory to the list of directories in which the
2665/// interpreter looks for include files.
2666/// \param[in] path The path to the directory.
2667/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2668/// \b NOT supported.
2669/// \warning Only the path to the directory should be specified, without
2670/// prepending the \c -I prefix, i.e.
2671/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2672/// \c -I prefix is used it will be ignored.
2673void TCling::AddIncludePath(const char *path)
2674{
2676 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2677 // gCling->AddIncludePath() does not! Work around that inconsistency:
2678 if (path[0] == '-' && path[1] == 'I')
2679 path += 2;
2680 TString sPath(path);
2681 gSystem->ExpandPathName(sPath);
2682 fInterpreter->AddIncludePath(sPath.Data());
2683}
2684
2685////////////////////////////////////////////////////////////////////////////////
2686/// Visit all members over members, recursing over base classes.
2687
2688void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2689 const TClass* cl, Bool_t isTransient)
2690{
2694 }
2695
2696 if (!cl || cl->GetCollectionProxy()) {
2697 // We do not need to investigate the content of the STL
2698 // collection, they are opaque to us (and details are
2699 // uninteresting).
2700 return;
2701 }
2702
2703 static const TClassRef clRefString("std::string");
2704 if (clRefString == cl) {
2705 // We stream std::string without going through members..
2706 return;
2707 }
2708
2709 if (TClassEdit::IsStdArray(cl->GetName())) {
2710 // We treat std arrays as C arrays
2711 return;
2712 }
2713
2714 const char* cobj = (const char*) obj; // for ptr arithmetics
2715
2716 // Treat the case of std::complex in a special manner. We want to enforce
2717 // the layout of a stl implementation independent class, which is the
2718 // complex as implemented in ROOT5.
2719
2720 // A simple lambda to simplify the code
2721 auto inspInspect = [&] (ptrdiff_t offset){
2722 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2723 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2724 };
2725
2726 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2727 switch(complexType) {
2729 {
2730 break;
2731 }
2733 {
2734 inspInspect(sizeof(float));
2735 return;
2736 }
2738 {
2739 inspInspect(sizeof(double));
2740 return;
2741 }
2743 {
2744 inspInspect(sizeof(int));
2745 return;
2746 }
2748 {
2749 inspInspect(sizeof(long));
2750 return;
2751 }
2752 }
2753
2754 static clang::PrintingPolicy
2755 printPol(fInterpreter->getCI()->getLangOpts());
2756 if (printPol.Indentation) {
2757 // not yet initialized
2758 printPol.Indentation = 0;
2759 printPol.SuppressInitializers = true;
2760 }
2761
2762 const char* clname = cl->GetName();
2763 // Printf("Inspecting class %s\n", clname);
2764
2765 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2766 const clang::Decl *scopeDecl = 0;
2767 const clang::Type *recordType = 0;
2768
2769 if (cl->GetClassInfo()) {
2770 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2771 scopeDecl = clingCI->GetDecl();
2772 recordType = clingCI->GetType();
2773 } else {
2774 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2775 // Diags will complain about private classes:
2776 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2777 &recordType);
2778 }
2779 if (!scopeDecl) {
2780 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2781 return;
2782 }
2783 const clang::CXXRecordDecl* recordDecl
2784 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2785 if (!recordDecl) {
2786 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2787 return;
2788 }
2789
2790 {
2791 // Force possible deserializations first. We need to have no pending
2792 // Transaction when passing control flow to the inspector below (ROOT-7779).
2793 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2794
2795 astContext.getASTRecordLayout(recordDecl);
2796
2797 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2798 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2799 }
2800
2801 const clang::ASTRecordLayout& recLayout
2802 = astContext.getASTRecordLayout(recordDecl);
2803
2804 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2805 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2806 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2807 // cl->GetName());
2808 // }
2809 if (cl->Size() != recLayout.getSize().getQuantity()) {
2810 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2811 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2812 }
2813
2814 unsigned iNField = 0;
2815 // iterate over fields
2816 // FieldDecls are non-static, else it would be a VarDecl.
2817 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2818 eField = recordDecl->field_end(); iField != eField;
2819 ++iField, ++iNField) {
2820
2821
2822 clang::QualType memberQT = iField->getType();
2823 if (recordType) {
2824 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2825 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2826 }
2827 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2828 if (memberQT.isNull()) {
2829 std::string memberName;
2830 llvm::raw_string_ostream stream(memberName);
2831 // Don't trigger fopen of the source file to count lines:
2832 printPol.AnonymousTagLocations = false;
2833 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2834 stream.flush();
2835 Error("InspectMembers",
2836 "Cannot retrieve QualType for member %s while inspecting class %s",
2837 memberName.c_str(), clname);
2838 continue; // skip member
2839 }
2840 const clang::Type* memType = memberQT.getTypePtr();
2841 if (!memType) {
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 Type for member %s while inspecting class %s",
2850 memberName.c_str(), clname);
2851 continue; // skip member
2852 }
2853
2854 const clang::Type* memNonPtrType = memType;
2855 Bool_t ispointer = false;
2856 if (memNonPtrType->isPointerType()) {
2857 ispointer = true;
2858 clang::QualType ptrQT
2859 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2860 if (recordType) {
2861 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2862 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2863 }
2864 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2865 if (ptrQT.isNull()) {
2866 std::string memberName;
2867 llvm::raw_string_ostream stream(memberName);
2868 // Don't trigger fopen of the source file to count lines:
2869 printPol.AnonymousTagLocations = false;
2870 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2871 stream.flush();
2872 Error("InspectMembers",
2873 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2874 memberName.c_str(), clname);
2875 continue; // skip member
2876 }
2877 memNonPtrType = ptrQT.getTypePtr();
2878 }
2879
2880 // assemble array size(s): "[12][4][]"
2881 llvm::SmallString<8> arraySize;
2882 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2883 unsigned arrLevel = 0;
2884 bool haveErrorDueToArray = false;
2885 while (arrType) {
2886 ++arrLevel;
2887 arraySize += '[';
2888 const clang::ConstantArrayType* constArrType =
2889 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2890 if (constArrType) {
2891 constArrType->getSize().toStringUnsigned(arraySize);
2892 }
2893 arraySize += ']';
2894 clang::QualType subArrQT = arrType->getElementType();
2895 if (subArrQT.isNull()) {
2896 std::string memberName;
2897 llvm::raw_string_ostream stream(memberName);
2898 // Don't trigger fopen of the source file to count lines:
2899 printPol.AnonymousTagLocations = false;
2900 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2901 stream.flush();
2902 Error("InspectMembers",
2903 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2904 arrLevel, subArrQT.getAsString(printPol).c_str(),
2905 memberName.c_str(), clname);
2906 haveErrorDueToArray = true;
2907 break;
2908 }
2909 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2910 }
2911 if (haveErrorDueToArray) {
2912 continue; // skip member
2913 }
2914
2915 // construct member name
2916 std::string fieldName;
2917 if (memType->isPointerType()) {
2918 fieldName = "*";
2919 }
2920
2921 // Check if this field has a custom ioname, if not, just use the one of the decl
2922 std::string ioname(iField->getName());
2923 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2924 fieldName += ioname;
2925 fieldName += arraySize;
2926
2927 // get member offset
2928 // NOTE currently we do not support bitfield and do not support
2929 // member that are not aligned on 'bit' boundaries.
2930 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2931 ptrdiff_t fieldOffset = offset.getQuantity();
2932
2933 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2934 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2935 // R__insp.InspectMember(fName, "fName.");
2936 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2937
2938 // If the class has a custom streamer and the type of the filed is a
2939 // private enum, struct or class, skip it.
2940 if (!insp.IsTreatingNonAccessibleTypes()){
2941 auto iFiledQtype = iField->getType();
2942 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2943 auto declAccess = tagDecl->getAccess();
2944 if (declAccess == AS_private || declAccess == AS_protected) {
2945 continue;
2946 }
2947 }
2948 }
2949
2950 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2951
2952 if (!ispointer) {
2953 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2954 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2955 // nested objects get an extra call to InspectMember
2956 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2957 std::string sFieldRecName;
2958 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2960 clang::QualType(memNonPtrType,0),
2961 *fInterpreter,
2963 }
2964
2965 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2966 // if we can not find the member (which should not really happen),
2967 // let's consider it transient.
2968 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2969
2970 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2971 (fieldName + '.').c_str(), transient);
2972
2973 }
2974 }
2975 } // loop over fields
2976
2977 // inspect bases
2978 // TNamed::ShowMembers(R__insp);
2979 unsigned iNBase = 0;
2980 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2981 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2982 iBase != eBase; ++iBase, ++iNBase) {
2983 clang::QualType baseQT = iBase->getType();
2984 if (baseQT.isNull()) {
2985 Error("InspectMembers",
2986 "Cannot find QualType for base number %d while inspecting class %s",
2987 iNBase, clname);
2988 continue;
2989 }
2990 const clang::CXXRecordDecl* baseDecl
2991 = baseQT->getAsCXXRecordDecl();
2992 if (!baseDecl) {
2993 Error("InspectMembers",
2994 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2995 iNBase, clname);
2996 continue;
2997 }
2998 TClass* baseCl=nullptr;
2999 std::string sBaseName;
3000 // Try with the DeclId
3001 std::vector<TClass*> foundClasses;
3002 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3003 if (foundClasses.size()==1){
3004 baseCl=foundClasses[0];
3005 } else {
3006 // Try with the normalised Name, as a fallback
3007 if (!baseCl){
3009 baseQT,
3010 *fInterpreter,
3012 baseCl = TClass::GetClass(sBaseName.c_str());
3013 }
3014 }
3015
3016 if (!baseCl){
3017 std::string qualNameForDiag;
3018 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3019 Error("InspectMembers",
3020 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3021 continue;
3022 }
3023
3024 int64_t baseOffset;
3025 if (iBase->isVirtual()) {
3027 if (!isTransient) {
3028 Error("InspectMembers",
3029 "Base %s of class %s is virtual but no object provided",
3030 sBaseName.c_str(), clname);
3031 }
3033 } else {
3034 // We have an object to determine the vbase offset.
3036 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3037 if (ci && baseCi) {
3038 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3039 true /*isDerivedObj*/);
3040 if (baseOffset == -1) {
3041 Error("InspectMembers",
3042 "Error calculating offset of virtual base %s of class %s",
3043 sBaseName.c_str(), clname);
3044 }
3045 } else {
3046 Error("InspectMembers",
3047 "Cannot calculate offset of virtual base %s of class %s",
3048 sBaseName.c_str(), clname);
3049 continue;
3050 }
3051 }
3052 } else {
3053 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3054 }
3055 // TOFIX: baseCl can be null here!
3056 if (baseCl->IsLoaded()) {
3057 // For loaded class, CallShowMember will (especially for TObject)
3058 // call the virtual ShowMember rather than the class specific version
3059 // resulting in an infinite recursion.
3060 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3061 } else {
3062 baseCl->CallShowMembers(cobj + baseOffset,
3063 insp, isTransient);
3064 }
3065 } // loop over bases
3066}
3067
3068////////////////////////////////////////////////////////////////////////////////
3069/// Reset the interpreter internal state in case a previous action was not correctly
3070/// terminated.
3071
3073{
3074 // No-op there is not equivalent state (to be cleared) in Cling.
3075}
3076
3077////////////////////////////////////////////////////////////////////////////////
3078/// Delete existing temporary values.
3079
3081{
3082 // No-op for cling due to cling::Value.
3083}
3084
3085////////////////////////////////////////////////////////////////////////////////
3086/// Declare code to the interpreter, without any of the interpreter actions
3087/// that could trigger a re-interpretation of the code. I.e. make cling
3088/// behave like a compiler: no dynamic lookup, no input wrapping for
3089/// subsequent execution, no automatic provision of declarations but just a
3090/// plain `#include`.
3091/// Returns true on success, false on failure.
3092
3093bool TCling::Declare(const char* code)
3094{
3096
3097 SuspendAutoLoadingRAII autoLoadOff(this);
3098 SuspendAutoParsing autoParseRaii(this);
3099
3100 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3101 fInterpreter->enableDynamicLookup(false);
3102 bool oldRawInput = fInterpreter->isRawInputEnabled();
3103 fInterpreter->enableRawInput(true);
3104
3105 Bool_t ret = LoadText(code);
3106
3107 fInterpreter->enableRawInput(oldRawInput);
3108 fInterpreter->enableDynamicLookup(oldDynLookup);
3109 return ret;
3110}
3111
3112////////////////////////////////////////////////////////////////////////////////
3113/// It calls a "fantom" method to synchronize user keyboard input
3114/// and ROOT prompt line.
3115
3117{
3119}
3120
3121// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3122// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3123// was already taking a lock.
3124static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3125{
3126 // Check shared library.
3127 TString tLibName(libname);
3128 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3129 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3130 return false;
3131}
3132
3133Bool_t TCling::IsLibraryLoaded(const char* libname) const
3134{
3136 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3137}
3138
3139////////////////////////////////////////////////////////////////////////////////
3140/// Return true if ROOT has cxxmodules pcm for a given library name.
3141// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3142Bool_t TCling::HasPCMForLibrary(const char *libname) const
3143{
3144 llvm::StringRef ModuleName(libname);
3145 ModuleName = llvm::sys::path::stem(ModuleName);
3146 ModuleName.consume_front("lib");
3147
3148 // FIXME: In case when the modulemap is not yet loaded we will return the
3149 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3150 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3151 // which may happen after calling this interface. Maybe we should also check
3152 // if there is a Event.pcm file and a module.modulemap, load it and return
3153 // true.
3154 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3155 clang::Module *M = moduleMap.findModule(ModuleName);
3156 return M && !M->IsUnimportable && M->getASTFile();
3157}
3158
3159////////////////////////////////////////////////////////////////////////////////
3160/// Return true if the file has already been loaded by cint.
3161/// We will try in this order:
3162/// actual filename
3163/// filename as a path relative to
3164/// the include path
3165/// the shared library path
3166
3168{
3170
3171 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3172 // cling::DynamicLibraryManager.
3173
3174 std::string file_name = filename;
3175 size_t at = std::string::npos;
3176 while ((at = file_name.find("/./")) != std::string::npos)
3177 file_name.replace(at, 3, "/");
3178
3179 std::string filesStr = "";
3180 llvm::raw_string_ostream filesOS(filesStr);
3181 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3182 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3183 filesOS.flush();
3184
3185 llvm::SmallVector<llvm::StringRef, 100> files;
3186 llvm::StringRef(filesStr).split(files, "\n");
3187
3188 std::set<std::string> fileMap;
3189 llvm::StringRef file_name_ref(file_name);
3190 // Fill fileMap; return early on exact match.
3191 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3192 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3193 if ((*iF) == file_name_ref) return kTRUE; // exact match
3194 fileMap.insert(iF->str());
3195 }
3196
3197 if (fileMap.empty()) return kFALSE;
3198
3199 // Check MacroPath.
3200 TString sFilename(file_name.c_str());
3202 && fileMap.count(sFilename.Data())) {
3203 return kTRUE;
3204 }
3205
3206 // Check IncludePath.
3207 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3208 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3209 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3210 while (incPath.Index(" :") != -1) {
3211 incPath.ReplaceAll(" :", ":");
3212 }
3213 incPath.Prepend(".:");
3214 sFilename = file_name.c_str();
3215 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3216 && fileMap.count(sFilename.Data())) {
3217 return kTRUE;
3218 }
3219
3220 // Check shared library.
3221 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3222 return kTRUE;
3223
3224 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3225 const clang::DirectoryLookup *CurDir = 0;
3226 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3227 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3228 auto FE = HS.LookupFile(file_name.c_str(),
3229 clang::SourceLocation(),
3230 /*isAngled*/ false,
3231 /*FromDir*/ 0, CurDir,
3232 clang::ArrayRef<std::pair<const clang::FileEntry *,
3233 const clang::DirectoryEntry *>>(),
3234 /*SearchPath*/ 0,
3235 /*RelativePath*/ 0,
3236 /*RequestingModule*/ 0,
3237 /*SuggestedModule*/ 0,
3238 /*IsMapped*/ 0,
3239 /*IsFrameworkFound*/ nullptr,
3240 /*SkipCache*/ false,
3241 /*BuildSystemModule*/ false,
3242 /*OpenFile*/ false,
3243 /*CacheFail*/ false);
3244 if (FE && FE->isValid()) {
3245 // check in the source manager if the file is actually loaded
3246 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3247 // this works only with header (and source) files...
3248 clang::FileID FID = SM.translateFile(*FE);
3249 if (!FID.isInvalid() && FID.getHashValue() == 0)
3250 return kFALSE;
3251 else {
3252 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3253 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3254 return kFALSE;
3255 if (!FID.isInvalid())
3256 return kTRUE;
3257 }
3258 // ...then check shared library again, but with full path now
3259 sFilename = FE->getName().str();
3260 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3261 && fileMap.count(sFilename.Data())) {
3262 return kTRUE;
3263 }
3264 }
3265 return kFALSE;
3266}
3267
3268
3269#if defined(R__MACOSX)
3270
3271////////////////////////////////////////////////////////////////////////////////
3272/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3273/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3274/// to `-lFOO` such that it can be passed to the linker.
3275/// This is a unique feature of macOS 11.
3276
3277static bool R__UpdateLibFileForLinking(TString &lib)
3278{
3279 const char *mapfile = nullptr;
3280#if __x86_64__
3281 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3282#elif __arm64__
3283 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3284#else
3285 #error unsupported architecture
3286#endif
3287 if (std::ifstream cacheMap{mapfile}) {
3288 std::string line;
3289 while (getline(cacheMap, line)) {
3290 if (line.find(lib) != std::string::npos) {
3291 lib.ReplaceAll("/usr/lib/lib","-l");
3292 lib.ReplaceAll(".dylib","");
3293 return true;
3294 }
3295 }
3296 return false;
3297 }
3298 return false;
3299}
3300#endif // R__MACOSX
3301
3302#ifdef R__LINUX
3303
3304////////////////////////////////////////////////////////////////////////////////
3305/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3306/// Collects opened libraries.
3307
3308static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3309{
3310 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3311 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3312
3313 auto newLibs = static_cast<std::vector<std::string>*>(data);
3314 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3315 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3316 if (info->dlpi_name && info->dlpi_name[0]
3317 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3318 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3319 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3320 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3321 newLibs->emplace_back(info->dlpi_name);
3322 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3323 }
3324 // No matter what the doc says, return != 0 means "stop the iteration".
3325 return 0;
3326}
3327
3328#endif // R__LINUX
3329
3330
3331////////////////////////////////////////////////////////////////////////////////
3332
3334{
3335#if defined(R__WIN32) || defined(__CYGWIN__)
3336 HMODULE hModules[1024];
3337 void *hProcess;
3338 unsigned long cbModules;
3339 unsigned int i;
3340 hProcess = (void *)::GetCurrentProcess();
3341 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3342 // start at 1 to skip the executable itself
3343 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3344 static const int bufsize = 260;
3345 wchar_t winname[bufsize];
3346 char posixname[bufsize];
3347 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3348#if defined(__CYGWIN__)
3349 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3350#else
3351 std::wstring wpath = winname;
3352 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3353 string path(wpath.begin(), wpath.end());
3354 strncpy(posixname, path.c_str(), bufsize);
3355#endif
3356 if (!fSharedLibs.Contains(posixname)) {
3357 RegisterLoadedSharedLibrary(posixname);
3358 }
3359 }
3360#elif defined(R__MACOSX)
3361 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3362 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3363
3364 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3365 // Skip non-dylibs
3366 if (mh->filetype == MH_DYLIB) {
3367 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3368 RegisterLoadedSharedLibrary(imageName);
3369 }
3370 }
3371
3372 ++imageIndex;
3373 }
3374 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3375#elif defined(R__LINUX)
3376 // fPrevLoadedDynLibInfo is unused on Linux.
3377 (void) fPrevLoadedDynLibInfo;
3378
3379 std::vector<std::string> newLibs;
3380 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3381 for (auto &&lib: newLibs)
3382 RegisterLoadedSharedLibrary(lib.c_str());
3383#else
3384 Error("TCling::UpdateListOfLoadedSharedLibraries",
3385 "Platform not supported!");
3386#endif
3387}
3388
3389namespace {
3390template <int N>
3391static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3392 return !strncmp(haystack, needle, N - 1);
3393}
3394}
3395
3396////////////////////////////////////////////////////////////////////////////////
3397/// Register a new shared library name with the interpreter; add it to
3398/// fSharedLibs.
3399
3401{
3402 // Ignore NULL filenames, aka "the process".
3403 if (!filename) return;
3404
3405 // Tell the interpreter that this library is available; all libraries can be
3406 // used to resolve symbols.
3407 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3408 if (!DLM->isLibraryLoaded(filename)) {
3409 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3410 }
3411
3412#if defined(R__MACOSX)
3413 // Check that this is not a system library that does not exist on disk.
3414 auto lenFilename = strlen(filename);
3415 auto isInMacOSSystemDir = [](const char *fn) {
3416 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3417 };
3418 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3419
3420 // These we should not link with (e.g. because they forward to .tbd):
3421 || StartsWithStrLit(filename, "/usr/lib/system/")
3422 || StartsWithStrLit(filename, "/usr/lib/libc++")
3423 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3424 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3425 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3426 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3427 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3428 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3429 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3430 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3431 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3432 || StartsWithStrLit(filename, "/usr/lib/libauto")
3433 || StartsWithStrLit(filename, "/usr/lib/libcups")
3434 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3435 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3436 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3437 || StartsWithStrLit(filename, "/usr/lib/libpam")
3438 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3439 || StartsWithStrLit(filename, "/usr/lib/libextension")
3440 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3441 || StartsWithStrLit(filename, "/usr/lib/liboah")
3442 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3443 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3444 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3445 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3446
3447 // The system lib is likely in macOS's blob.
3448 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3449
3450 // "Link against the umbrella framework 'System.framework' instead"
3451 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3452 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3453 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3454
3455 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3456 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3457 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3458 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3459 return;
3460 TString sFileName(filename);
3461 R__UpdateLibFileForLinking(sFileName);
3462 filename = sFileName.Data();
3463#elif defined(__CYGWIN__)
3464 // Check that this is not a system library
3465 static const int bufsize = 260;
3466 char posixwindir[bufsize];
3467 char *windir = getenv("WINDIR");
3468 if (windir)
3469 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3470 else
3471 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3472 if (strstr(filename, posixwindir) ||
3473 strstr(filename, "/usr/bin/cyg"))
3474 return;
3475#elif defined(R__WIN32)
3476 if (strstr(filename, "/Windows/"))
3477 return;
3478#elif defined (R__LINUX)
3479 if (strstr(filename, "/ld-linux")
3480 || strstr(filename, "linux-gnu/")
3481 || strstr(filename, "/libstdc++.")
3482 || strstr(filename, "/libgcc")
3483 || strstr(filename, "/libc.")
3484 || strstr(filename, "/libdl.")
3485 || strstr(filename, "/libm."))
3486 return;
3487#endif
3488 // Update string of available libraries.
3489 if (!fSharedLibs.IsNull()) {
3490 fSharedLibs.Append(" ");
3491 }
3493}
3494
3495////////////////////////////////////////////////////////////////////////////////
3496/// Load a library file in cling's memory.
3497/// if 'system' is true, the library is never unloaded.
3498/// Return 0 on success, -1 on failure.
3499
3500Int_t TCling::Load(const char* filename, Bool_t system)
3501{
3502 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3503
3504 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3506 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3507 std::string canonLib = DLM->lookupLibrary(filename);
3508 cling::DynamicLibraryManager::LoadLibResult res
3509 = cling::DynamicLibraryManager::kLoadLibNotFound;
3510 if (!canonLib.empty()) {
3511 if (system)
3512 res = DLM->loadLibrary(filename, system, true);
3513 else {
3514 // For the non system libs, we'd like to be able to unload them.
3515 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3516 cling::Interpreter::CompilationResult compRes;
3517 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3518 if (compRes == cling::Interpreter::kSuccess)
3519 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3520 }
3521 }
3522
3523 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3525 }
3526 switch (res) {
3527 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3528 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3529 default: break;
3530 };
3531 return -1;
3532}
3533
3534////////////////////////////////////////////////////////////////////////////////
3535/// Load a macro file in cling's memory.
3536
3537void TCling::LoadMacro(const char* filename, EErrorCode* error)
3538{
3539 ProcessLine(Form(".L %s", filename), error);
3540}
3541
3542////////////////////////////////////////////////////////////////////////////////
3543/// Let cling process a command line asynch.
3544
3546{
3547 return ProcessLine(line, error);
3548}
3549
3550////////////////////////////////////////////////////////////////////////////////
3551/// Let cling process a command line synchronously, i.e we are waiting
3552/// it will be finished.
3553
3555{
3557 if (gApplication) {
3558 if (gApplication->IsCmdThread()) {
3559 return ProcessLine(line, error);
3560 }
3561 return 0;
3562 }
3563 return ProcessLine(line, error);
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3568/// however not declarations, like "Int_t x;").
3569
3571{
3572#ifdef R__WIN32
3573 // Test on ApplicationImp not being 0 is needed because only at end of
3574 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3575 // we can not use it.
3577 while (gROOT->IsLineProcessing() && !gApplication) {
3578 Warning("Calc", "waiting for cling thread to free");
3579 gSystem->Sleep(500);
3580 }
3581 gROOT->SetLineIsProcessing();
3582 }
3583#endif // R__WIN32
3585 if (error) {
3586 *error = TInterpreter::kNoError;
3587 }
3588 cling::Value valRef;
3589 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3590 try {
3591 cr = fInterpreter->evaluate(line, valRef);
3592 }
3593 catch (cling::InterpreterException& ex)
3594 {
3595 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3596 ex.diagnose();
3597 cr = cling::Interpreter::kFailure;
3598 }
3599
3600 if (cr != cling::Interpreter::kSuccess) {
3601 // Failure in compilation.
3602 if (error) {
3603 // Note: Yes these codes are weird.
3605 }
3606 return 0L;
3607 }
3608 if (!valRef.isValid()) {
3609 // Failure at runtime.
3610 if (error) {
3611 // Note: Yes these codes are weird.
3612 *error = TInterpreter::kDangerous;
3613 }
3614 return 0L;
3615 }
3616
3617 if (valRef.isVoid()) {
3618 return 0;
3619 }
3620
3621 RegisterTemporary(valRef);
3622#ifdef R__WIN32
3624 gROOT->SetLineHasBeenProcessed();
3625 }
3626#endif // R__WIN32
3627 return valRef.simplisticCastAs<Longptr_t>();
3628}
3629
3630////////////////////////////////////////////////////////////////////////////////
3631/// Set a getline function to call when input is needed.
3632
3633void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3634 void (*histaddFunc)(const char* line))
3635{
3636 // If cling offers a replacement for G__pause(), it would need to
3637 // also offer a way to customize at least the history recording.
3638
3639#if defined(R__MUST_REVISIT)
3640#if R__MUST_REVISIT(6,2)
3641 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3642#endif
3643#endif
3644}
3645
3646////////////////////////////////////////////////////////////////////////////////
3647/// Helper function to increase the internal Cling count of transactions
3648/// that change the AST.
3649
3650Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3651{
3653
3654 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3655 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3656 || T.macros_begin() != T.macros_end()
3657 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3659 return true;
3660 }
3661 return false;
3662}
3663
3664////////////////////////////////////////////////////////////////////////////////
3665/// Delete object from cling symbol table so it can not be used anymore.
3666/// cling objects are always on the heap.
3667
3669{
3670 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3671 // put in place the Read/Write part here. Keeping the write lock
3672 // here is 'catasptrophic' for scaling as it means that ALL calls
3673 // to RecursiveRemove will take the write lock and performance
3674 // of many threads trying to access the write lock at the same
3675 // time is relatively bad.
3677 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3678 // (but isn't at the moment).
3679 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3680 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3681 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3683 DeleteGlobal(obj);
3684 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3685 }
3686 }
3687}
3688
3689////////////////////////////////////////////////////////////////////////////////
3690/// Pressing Ctrl+C should forward here. In the case where we have had
3691/// continuation requested we must reset it.
3692
3694{
3695 fMetaProcessor->cancelContinuation();
3696 // Reset the Cling state to the state saved by the last call to
3697 // TCling::SaveContext().
3698#if defined(R__MUST_REVISIT)
3699#if R__MUST_REVISIT(6,2)
3701 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3702#endif
3703#endif
3704}
3705
3706////////////////////////////////////////////////////////////////////////////////
3707/// Reset the Cling state to its initial state.
3708
3710{
3711#if defined(R__MUST_REVISIT)
3712#if R__MUST_REVISIT(6,2)
3714 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3715#endif
3716#endif
3717}
3718
3719////////////////////////////////////////////////////////////////////////////////
3720/// Reset in Cling the list of global variables to the state saved by the last
3721/// call to TCling::SaveGlobalsContext().
3722///
3723/// Note: Right now, all we do is run the global destructors.
3724
3726{
3728 // TODO:
3729 // Here we should iterate over the transactions (N-3) and revert.
3730 // N-3 because the first three internal to cling.
3731
3732 fInterpreter->runAndRemoveStaticDestructors();
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3737/// call to TCling::SaveGlobalsContext().
3738
3740{
3741#if defined(R__MUST_REVISIT)
3742#if R__MUST_REVISIT(6,2)
3744 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3745#endif
3746#endif
3747}
3748
3749////////////////////////////////////////////////////////////////////////////////
3750/// Rewind Cling dictionary to the point where it was before executing
3751/// the current macro. This function is typically called after SEGV or
3752/// ctlr-C after doing a longjmp back to the prompt.
3753
3755{
3756#if defined(R__MUST_REVISIT)
3757#if R__MUST_REVISIT(6,2)
3759 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3760#endif
3761#endif
3762}
3763
3764////////////////////////////////////////////////////////////////////////////////
3765/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3766/// Returns 1 in case of success and 0 in case object was not in table.
3767
3769{
3770#if defined(R__MUST_REVISIT)
3771#if R__MUST_REVISIT(6,2)
3773 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3774#endif
3775#endif
3776 return 0;
3777}
3778
3779////////////////////////////////////////////////////////////////////////////////
3780/// Undeclare obj called name.
3781/// Returns 1 in case of success, 0 for failure.
3782
3784{
3785#if defined(R__MUST_REVISIT)
3786#if R__MUST_REVISIT(6,2)
3787 Warning("DeleteVariable","should do more that just reseting the value to zero");
3788#endif
3789#endif
3790
3792 llvm::StringRef srName(name);
3793 const char* unscopedName = name;
3794 llvm::StringRef::size_type posScope = srName.rfind("::");
3795 const clang::DeclContext* declCtx = 0;
3796 if (posScope != llvm::StringRef::npos) {
3797 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3798 const clang::Decl* scopeDecl
3799 = lh.findScope(srName.substr(0, posScope),
3800 cling::LookupHelper::WithDiagnostics);
3801 if (!scopeDecl) {
3802 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3803 name);
3804 return 0;
3805 }
3806 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3807 if (!declCtx) {
3808 Error("DeleteVariable",
3809 "Enclosing scope for variable %s is not a declaration context",
3810 name);
3811 return 0;
3812 }
3813 unscopedName += posScope + 2;
3814 }
3815 // Could trigger deserialization of decls.
3816 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3817 clang::NamedDecl* nVarDecl
3818 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3819 if (!nVarDecl) {
3820 Error("DeleteVariable", "Unknown variable %s", name);
3821 return 0;
3822 }
3823 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3824 if (!varDecl) {
3825 Error("DeleteVariable", "Entity %s is not a variable", name);
3826 return 0;
3827 }
3828
3829 clang::QualType qType = varDecl->getType();
3830 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3831 // Cannot set a reference's address to nullptr; the JIT can place it
3832 // into read-only memory (ROOT-7100).
3833 if (type->isPointerType()) {
3834 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3835 // set pointer to invalid.
3836 if (ppInt) *ppInt = 0;
3837 }
3838 return 1;
3839}
3840
3841////////////////////////////////////////////////////////////////////////////////
3842/// Save the current Cling state.
3843
3845{
3846#if defined(R__MUST_REVISIT)
3847#if R__MUST_REVISIT(6,2)
3849 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3850#endif
3851#endif
3852}
3853
3854////////////////////////////////////////////////////////////////////////////////
3855/// Save the current Cling state of global objects.
3856
3858{
3859#if defined(R__MUST_REVISIT)
3860#if R__MUST_REVISIT(6,2)
3862 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3863#endif
3864#endif
3865}
3866
3867////////////////////////////////////////////////////////////////////////////////
3868/// No op: see TClingCallbacks (used to update the list of globals)
3869
3871{
3872}
3873
3874////////////////////////////////////////////////////////////////////////////////
3875/// No op: see TClingCallbacks (used to update the list of global functions)
3876
3878{
3879}
3880
3881////////////////////////////////////////////////////////////////////////////////
3882/// No op: see TClingCallbacks (used to update the list of types)
3883
3885{
3886}
3887
3888////////////////////////////////////////////////////////////////////////////////
3889/// Check in what order the member of a tuple are layout.
3890enum class ETupleOrdering {
3891 kAscending,
3894};
3895
3897{
3900};
3901
3903{
3906};
3907
3909{
3910 std::tuple<int,double> value;
3913
3914 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3915 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3916
3917 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3918 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3919
3920 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3921 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3922
3923 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3925 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3927 } else {
3929 }
3930}
3931
3932static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3933{
3934 TClassEdit::TSplitType tupleContent(classname);
3935 std::string alternateName = "TEmulatedTuple";
3936 alternateName.append( classname + 5 );
3937
3938 std::string fullname = "ROOT::Internal::" + alternateName;
3939 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3940 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3941 return fullname;
3942
3943 std::string guard_name;
3944 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3945 std::ostringstream guard;
3946 guard << "ROOT_INTERNAL_TEmulated_";
3947 guard << guard_name;
3948
3949 std::ostringstream alternateTuple;
3950 alternateTuple << "#ifndef " << guard.str() << "\n";
3951 alternateTuple << "#define " << guard.str() << "\n";
3952 alternateTuple << "namespace ROOT { namespace Internal {\n";
3953 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3954 alternateTuple << "template <> struct " << alternateName << " {\n";
3955
3956 // This could also be a compile time choice ...
3957 switch(IsTupleAscending()) {
3959 unsigned int nMember = 0;
3960 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3961 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3962 while (iter != theEnd) {
3963 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3964 ++iter;
3965 ++nMember;
3966 }
3967 break;
3968 }
3970 unsigned int nMember = tupleContent.fElements.size() - 3;
3971 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3972 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3973 while (iter != theEnd) {
3974 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3975 ++iter;
3976 --nMember;
3977 }
3978 break;
3979 }
3981 Fatal("TCling::SetClassInfo::AlternateTuple",
3982 "Layout of std::tuple on this platform is unexpected.");
3983 break;
3984 }
3985 }
3986
3987 alternateTuple << "};\n";
3988 alternateTuple << "}}\n";
3989 alternateTuple << "#endif\n";
3990 if (!gCling->Declare(alternateTuple.str().c_str())) {
3991 Error("Load","Could not declare %s",alternateName.c_str());
3992 return "";
3993 }
3994 alternateName = "ROOT::Internal::" + alternateName;
3995 return alternateName;
3996}
3997
3998////////////////////////////////////////////////////////////////////////////////
3999/// Set pointer to the TClingClassInfo in TClass.
4000/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4001/// already have one.
4002
4004{
4005 // We are shutting down, there is no point in reloading, it only triggers
4006 // redundant deserializations.
4007 if (fIsShuttingDown) {
4008 // Remove the decl_id from the DeclIdToTClass map
4009 if (cl->fClassInfo) {
4011 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4012 // Test again as another thread may have set fClassInfo to nullptr.
4013 if (TClinginfo) {
4014 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4015 }
4016 delete TClinginfo;
4017 cl->fClassInfo = nullptr;
4018 }
4019 return;
4020 }
4021
4023 if (cl->fClassInfo && !reload) {
4024 return;
4025 }
4026 //Remove the decl_id from the DeclIdToTClass map
4027 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4028 if (TClinginfo) {
4029 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4030 }
4031 delete TClinginfo;
4032 cl->fClassInfo = 0;
4033 std::string name(cl->GetName());
4034
4035 auto SetWithoutClassInfoState = [](TClass *cl)
4036 {
4037 if (cl->fState != TClass::kHasTClassInit) {
4038 if (cl->fStreamerInfo->GetEntries() != 0) {
4040 } else {
4042 }
4043 }
4044 };
4045 // Handle the special case of 'tuple' where we ignore the real implementation
4046 // details and just overlay a 'simpler'/'simplistic' version that is easy
4047 // for the I/O to understand and handle.
4048 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4049 if (!reload)
4050 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
4051 if (reload || name.empty()) {
4052 // We could not generate the alternate
4053 SetWithoutClassInfoState(cl);
4054 return;
4055 }
4056 }
4057
4058 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4059 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4060 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4061 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4062 // TClingClassInfoReadOnly.
4063 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4064 if (!info->IsValid()) {
4065 SetWithoutClassInfoState(cl);
4066 delete info;
4067 return;
4068 }
4069 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4070 // In case a class contains an external enum, the enum will be seen as a
4071 // class. We must detect this special case and make the class a Zombie.
4072 // Here we assume that a class has at least one method.
4073 // We can NOT call TClass::Property from here, because this method
4074 // assumes that the TClass is well formed to do a lot of information
4075 // caching. The method SetClassInfo (i.e. here) is usually called during
4076 // the building phase of the TClass, hence it is NOT well formed yet.
4077 Bool_t zombieCandidate = kFALSE;
4078 if (
4079 info->IsValid() &&
4080 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4081 ) {
4082 zombieCandidate = kTRUE;
4083 }
4084 if (!info->IsLoaded()) {
4085 if (info->Property() & (kIsNamespace)) {
4086 // Namespaces can have info but no corresponding CINT dictionary
4087 // because they are auto-created if one of their contained
4088 // classes has a dictionary.
4089 zombieCandidate = kTRUE;
4090 }
4091 // this happens when no dictionary is available
4092 delete info;
4093 cl->fClassInfo = 0;
4094 }
4095 if (zombieCandidate && !cl->GetCollectionType()) {
4096 cl->MakeZombie();
4097 }
4098 // If we reach here, the info was valid (See early returns).
4099 if (cl->fState != TClass::kHasTClassInit) {
4100 if (cl->fClassInfo) {
4103 } else {
4104// if (TClassEdit::IsSTLCont(cl->GetName()) {
4105// There will be an emulated collection proxy, is that the same?
4106// cl->fState = TClass::kEmulated;
4107// } else {
4108 if (cl->fStreamerInfo->GetEntries() != 0) {
4110 } else {
4112 }
4113// }
4114 }
4115 }
4116 if (cl->fClassInfo) {
4117 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4118 }
4119}
4120
4121////////////////////////////////////////////////////////////////////////////////
4122/// Checks if an entity with the specified name is defined in Cling.
4123/// Returns kUnknown if the entity is not defined.
4124/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4125/// Returns kKnown if the entity is defined.
4126///
4127/// By default, structs, namespaces, classes, enums and unions are looked for.
4128/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4129/// namespaces only are considered. I.e. if the name is an enum or a union,
4130/// the returned value is false.
4131///
4132/// In the case where the class is not loaded and belongs to a namespace
4133/// or is nested, looking for the full class name is outputting a lots of
4134/// (expected) error messages. Currently the only way to avoid this is to
4135/// specifically check that each level of nesting is already loaded.
4136/// In case of templates the idea is that everything between the outer
4137/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4138
4140TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4141{
4143 static const char *anonEnum = "anonymous enum ";
4144 static const int cmplen = strlen(anonEnum);
4145
4146 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4147 return kUnknown;
4148 }
4149
4150 // Do not turn on the AutoLoading if it is globally off.
4151 autoload = autoload && IsClassAutoLoadingEnabled();
4152
4153 // Avoid the double search below in case the name is a fundamental type
4154 // or typedef to a fundamental type.
4155 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4156 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4157
4158 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4159 && fundType->GetType() > 0) {
4160 // Fundamental type, no a class.
4161 return kUnknown;
4162 }
4163
4164 // Migrated from within TClass::GetClass
4165 // If we want to know if a class or a namespace with this name exists in the
4166 // interpreter and this is an enum in the type system, before or after loading
4167 // according to the autoload function argument, return kUnknown.
4168 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4169 return kUnknown;
4170
4171 const char *classname = name;
4172
4173 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4174 class MaybeSuspendAutoLoadParse {
4175 int fStoreAutoLoad = 0;
4176 int fStoreAutoParse = 0;
4177 bool fSuspendedAutoParse = false;
4178 public:
4179 MaybeSuspendAutoLoadParse(int autoload) {
4180 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4181 }
4182
4183 void SuspendAutoParsing() {
4184 fSuspendedAutoParse = true;
4185 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4186 }
4187
4188 ~MaybeSuspendAutoLoadParse() {
4189 if (fSuspendedAutoParse)
4190 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4191 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4192 }
4193 };
4194
4195 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4196 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4197 autoLoadParseRAII.SuspendAutoParsing();
4198
4199 // First we want to check whether the decl exist, but _without_
4200 // generating any template instantiation. However, the lookup
4201 // still will create a forward declaration of the class template instance
4202 // if it exist. In this case, the return value of findScope will still
4203 // be zero but the type will be initialized.
4204 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4205 // this forward declaration.
4206 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4207 const clang::Type *type = 0;
4208 const clang::Decl *decl
4209 = lh.findScope(classname,
4210 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4211 : cling::LookupHelper::NoDiagnostics,
4212 &type, /* intantiateTemplate= */ false );
4213 if (!decl) {
4214 std::string buf = TClassEdit::InsertStd(classname);
4215 decl = lh.findScope(buf,
4216 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4217 : cling::LookupHelper::NoDiagnostics,
4218 &type,false);
4219 }
4220
4221 if (type) {
4222 // If decl==0 and the type is valid, then we have a forward declaration.
4223 if (!decl) {
4224 // If we have a forward declaration for a class template instantiation,
4225 // we want to ignore it if it was produced/induced by the call to
4226 // findScope, however we can not distinguish those from the
4227 // instantiation induce by 'soft' use (and thus also induce by the
4228 // same underlying code paths)
4229 // ['soft' use = use not requiring a complete definition]
4230 // So to reduce the amount of disruption to the existing code we
4231 // would just ignore those for STL collection, for which we really
4232 // need to have the compiled collection proxy (and thus the TClass
4233 // bootstrap).
4234 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4235 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4236 (type->getAsCXXRecordDecl());
4237 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4238 // Since the point of instantiation is invalid, we 'guess' that
4239 // the 'instantiation' of the forwarded type appended in
4240 // findscope.
4241 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4242 // For STL Collection we return kUnknown.
4243 return kUnknown;
4244 }
4245 }
4246 }
4248 if (!tci.IsValid()) {
4249 return kUnknown;
4250 }
4251 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4253
4254 if (tci.Property() & propertiesMask) {
4255 bool hasClassDefInline = false;
4256 if (isClassOrNamespaceOnly) {
4257 // We do not need to check for ClassDefInline when this is called from
4258 // TClass::Init, we only do it for the call from TClass::GetClass.
4259 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
4260 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
4261
4262 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4263 int lineNumber = 0;
4264 bool success = false;
4265 std::tie(success, lineNumber) =
4266 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4267 hasClassDefInline = success && (lineNumber == -1);
4268 }
4269 }
4270
4271 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4272 // , hasClassDefInline);
4273
4274 // We are now sure that the entry is not in fact an autoload entry.
4275 if (hasClassDefInline)
4276 return kWithClassDefInline;
4277 else
4278 return kKnown;
4279 } else {
4280 // We are now sure that the entry is not in fact an autoload entry.
4281 return kUnknown;
4282 }
4283 }
4284
4285 if (decl)
4286 return kKnown;
4287 else
4288 return kUnknown;
4289
4290 // Setting up iterator part of TClingTypedefInfo is too slow.
4291 // Copy the lookup code instead:
4292 /*
4293 TClingTypedefInfo t(fInterpreter, name);
4294 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4295 delete[] classname;
4296 return kTRUE;
4297 }
4298 */
4299
4300// const clang::Decl *decl = lh.findScope(name);
4301// if (!decl) {
4302// std::string buf = TClassEdit::InsertStd(name);
4303// decl = lh.findScope(buf);
4304// }
4305
4306// return (decl);
4307}
4308
4309////////////////////////////////////////////////////////////////////////////////
4310/// Return true if there is a class template by the given name ...
4311
4313{
4314 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4315 const clang::Decl *decl
4316 = lh.findClassTemplate(name,
4317 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4318 : cling::LookupHelper::NoDiagnostics);
4319 if (!decl) {
4320 std::string strname = "std::";
4321 strname += name;
4322 decl = lh.findClassTemplate(strname,
4323 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4324 : cling::LookupHelper::NoDiagnostics);
4325 }
4326 return 0 != decl;
4327}
4328
4329////////////////////////////////////////////////////////////////////////////////
4330/// Create list of pointers to base class(es) for TClass cl.
4331
4333{
4335 if (cl->fBase) {
4336 return;
4337 }
4339 if (!tci) return;
4341 TList *listOfBase = new TList;
4342 while (t.Next()) {
4343 // if name cannot be obtained no use to put in list
4344 if (t.IsValid() && t.Name()) {
4346 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4347 }
4348 }
4349 // Now that is complete, publish it.
4350 cl->fBase = listOfBase;
4351}
4352
4353////////////////////////////////////////////////////////////////////////////////
4354/// Create list of pointers to enums for TClass cl.
4355
4356void TCling::LoadEnums(TListOfEnums& enumList) const
4357{
4359
4360 const Decl * D;
4361 TClass* cl = enumList.GetClass();
4362 if (cl) {
4363 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4364 }
4365 else {
4366 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4367 }
4368 // Iterate on the decl of the class and get the enums.
4369 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4370 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4371 // Collect all contexts of the namespace.
4372 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4373 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4374 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4375 declIter != declEnd; ++declIter) {
4376 // Iterate on all decls for each context.
4377 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4378 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4379 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4380 // Get name of the enum type.
4381 std::string buf;
4382 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4383 llvm::raw_string_ostream stream(buf);
4384 // Don't trigger fopen of the source file to count lines:
4385 Policy.AnonymousTagLocations = false;
4386 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4387 stream.flush();
4388 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4389 if (!buf.empty()) {
4390 const char* name = buf.c_str();
4391 // Add the enum to the list of loaded enums.
4392 enumList.Get(ED, name);
4393 }
4394 }
4395 }
4396 }
4397 }
4398}
4399
4400////////////////////////////////////////////////////////////////////////////////
4401/// Create list of pointers to function templates for TClass cl.
4402
4404{
4406
4407 const Decl * D;
4408 TListOfFunctionTemplates* funcTempList;
4409 if (cl) {
4410 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4411 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4412 }
4413 else {
4414 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4415 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4416 }
4417 // Iterate on the decl of the class and get the enums.
4418 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4419 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4420 // Collect all contexts of the namespace.
4421 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4422 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4423 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4424 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4425 // Iterate on all decls for each context.
4426 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4427 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4428 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4429 funcTempList->Get(FTD);
4430 }
4431 }
4432 }
4433 }
4434}
4435
4436////////////////////////////////////////////////////////////////////////////////
4437/// Get the scopes representing using declarations of namespace
4438
4439std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4440{
4442 return ci->GetUsingNamespaces();
4443}
4444
4445////////////////////////////////////////////////////////////////////////////////
4446/// Create list of pointers to data members for TClass cl.
4447/// This is now a nop. The creation and updating is handled in
4448/// TListOfDataMembers.
4449
4451{
4452}
4453
4454////////////////////////////////////////////////////////////////////////////////
4455/// Create list of pointers to methods for TClass cl.
4456/// This is now a nop. The creation and updating is handled in
4457/// TListOfFunctions.
4458
4460{
4461}
4462
4463////////////////////////////////////////////////////////////////////////////////
4464/// Update the list of pointers to method for TClass cl
4465/// This is now a nop. The creation and updating is handled in
4466/// TListOfFunctions.
4467
4469{
4470}
4471
4472////////////////////////////////////////////////////////////////////////////////
4473/// Update the list of pointers to data members for TClass cl
4474/// This is now a nop. The creation and updating is handled in
4475/// TListOfDataMembers.
4476
4478{
4479}
4480
4481////////////////////////////////////////////////////////////////////////////////
4482/// Create list of pointers to method arguments for TMethod m.
4483
4485{
4487 if (m->fMethodArgs) {
4488 return;
4489 }
4490 TList *arglist = new TList;
4492 while (t.Next()) {
4493 if (t.IsValid()) {
4495 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4496 }
4497 }
4498 m->fMethodArgs = arglist;
4499}
4500
4501////////////////////////////////////////////////////////////////////////////////
4502/// Return whether we are waiting for more input either because the collected
4503/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4504
4506{
4507 return fMetaProcessor->awaitingMoreInput();
4508}
4509
4510////////////////////////////////////////////////////////////////////////////////
4511/// Generate a TClass for the given class.
4512/// Since the caller has already check the ClassInfo, let it give use the
4513/// result (via the value of emulation) rather than recalculate it.
4514
4515TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4516{
4517// For now the following line would lead to the (unwanted) instantiation
4518// of class template. This could/would need to be resurrected only if
4519// we re-introduce so sort of automatic instantiation. However this would
4520// have to include carefull look at the template parameter to avoid
4521// creating instance we can not really use (if the parameter are only forward
4522// declaration or do not have all the necessary interfaces).
4523
4524 // TClingClassInfo tci(fInterpreter, classname);
4525 // if (1 || !tci.IsValid()) {
4526
4527 Version_t version = 1;
4528 if (TClassEdit::IsSTLCont(classname)) {
4529 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4530 }
4532 TClass *cl = new TClass(classname, version, silent);
4533 if (emulation) {
4535 } else {
4536 // Set the class version if the class is versioned.
4537 // Note that we cannot just call CLASS::Class_Version() as we might not have
4538 // an execution engine (when invoked from rootcling).
4539
4540 // Do not call cl->GetClassVersion(), it has side effects!
4541 Version_t oldvers = cl->fClassVersion;
4542 if (oldvers == version && cl->GetClassInfo()) {
4543 // We have a version and it might need an update.
4545 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4546 // Namespaces don't have class versions.
4547 return cl;
4548 }
4549 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4552 if (!mi.IsValid()) {
4553 if (cl->TestBit(TClass::kIsTObject)) {
4554 Error("GenerateTClass",
4555 "Cannot find %s::Class_Version()! Class version might be wrong.",
4556 cl->GetName());
4557 }
4558 return cl;
4559 }
4560 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4561 *fInterpreter);
4562 if (newvers == -1) {
4563 // Didn't manage to determine the class version from the AST.
4564 // Use runtime instead.
4565 if ((mi.Property() & kIsStatic)
4566 && !fInterpreter->isInSyntaxOnlyMode()) {
4567 // This better be a static function.
4569 callfunc.SetFunc(&mi);
4570 newvers = callfunc.ExecInt(0);
4571 } else {
4572 Error("GenerateTClass",
4573 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4574 cl->GetName());
4575 }
4576 }
4577 if (newvers != oldvers) {
4578 cl->fClassVersion = newvers;
4579 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4580 }
4581 }
4582 }
4583
4584 return cl;
4585
4586// } else {
4587// return GenerateTClass(&tci,silent);
4588// }
4589}
4590
4591#if 0
4592////////////////////////////////////////////////////////////////////////////////
4593
4594static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4595{
4596 includes += info->FileName();
4597
4598 const clang::ClassTemplateSpecializationDecl *templateCl
4599 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4600 if (templateCl) {
4601 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4602 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4603 if (arg.getKind() == clang::TemplateArgument::Type) {
4604 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4605
4606 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4607 // We really need a header file.
4608 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4609 if (argdecl) {
4610 includes += ";";
4611 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4612 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4613 } else {
4614 std::string Result;
4615 llvm::raw_string_ostream OS(Result);
4616 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4617 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4618 }
4619 }
4620 }
4621 }
4622 }
4623}
4624#endif
4625
4626////////////////////////////////////////////////////////////////////////////////
4627/// Generate a TClass for the given class.
4628
4629TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4630{
4631 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4632 if (!info || !info->IsValid()) {
4633 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4634 return 0;
4635 }
4636 // We are in the case where we have AST nodes for this class.
4637 TClass *cl = 0;
4638 std::string classname;
4639 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4640 if (TClassEdit::IsSTLCont(classname)) {
4641#if 0
4642 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4643 // We need to build up the list of required headers, by
4644 // looking at each template arguments.
4645 TString includes;
4646 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4647
4648 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4649 // 0 means success.
4650 cl = TClass::LoadClass(classnam.c_str(), silent);
4651 if (cl == 0) {
4652 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4653 }
4654 }
4655#endif
4656 if (cl == 0) {
4657 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4658 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4660 }
4661 } else {
4662 // For regular class, just create a TClass on the fly ...
4663 // Not quite useful yet, but that what CINT used to do anyway.
4664 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4665 }
4666 // Add the new TClass to the map of declid and TClass*.
4667 if (cl) {
4669 }
4670 return cl;
4671}
4672
4673////////////////////////////////////////////////////////////////////////////////
4674/// Generate the dictionary for the C++ classes listed in the first
4675/// argument (in a semi-colon separated list).
4676/// 'includes' contains a semi-colon separated list of file to
4677/// `#include` in the dictionary.
4678/// For example:
4679/// ~~~ {.cpp}
4680/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4681/// ~~~
4682/// or
4683/// ~~~ {.cpp}
4684/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4685/// ~~~
4686
4687Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4688{
4689 if (classes == 0 || classes[0] == 0) {
4690 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4691 return 0;
4692 }
4693 // Split the input list
4694 std::vector<std::string> listClasses;
4695 for (
4696 const char* current = classes, *prev = classes;
4697 *current != 0;
4698 ++current
4699 ) {
4700 if (*current == ';') {
4701 listClasses.push_back(std::string(prev, current - prev));
4702 prev = current + 1;
4703 }
4704 else if (*(current + 1) == 0) {
4705 listClasses.push_back(std::string(prev, current + 1 - prev));
4706 prev = current + 1;
4707 }
4708 }
4709 std::vector<std::string> listIncludes;
4710 if (!includes)
4711 includes = "";
4712 for (
4713 const char* current = includes, *prev = includes;
4714 *current != 0;
4715 ++current
4716 ) {
4717 if (*current == ';') {
4718 listIncludes.push_back(std::string(prev, current - prev));
4719 prev = current + 1;
4720 }
4721 else if (*(current + 1) == 0) {
4722 listIncludes.push_back(std::string(prev, current + 1 - prev));
4723 prev = current + 1;
4724 }
4725 }
4726 // Generate the temporary dictionary file
4727 return !TCling_GenerateDictionary(listClasses, listIncludes,
4728 std::vector<std::string>(), std::vector<std::string>());
4729}
4730
4731////////////////////////////////////////////////////////////////////////////////
4732/// Return pointer to cling Decl of global/static variable that is located
4733/// at the address given by addr.
4734
4735TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4736{
4738 DeclId_t d;
4739 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4740
4741 // Could trigger deserialization of decls.
4742 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4743
4744 if (cl) {
4745 d = cl->GetDataMember(name);
4746 // We check if the decl of the data member has an annotation which indicates
4747 // an ioname.
4748 // In case this is true, if the name requested is not the ioname, we
4749 // return 0, as if the member did not exist. In some sense we override
4750 // the information in the TClassInfo instance, isolating the typesystem in
4751 // TClass from the one in the AST.
4752 if (const ValueDecl* decl = (const ValueDecl*) d){
4753 std::string ioName;
4754 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4755 if (hasIoName && ioName != name) return 0;
4756 }
4757 return d;
4758 }
4759 // We are looking up for something on the TU scope.
4760 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4761 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4762 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4763 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4764 // are only fulfilling ROOT's understanding for a Data Member.
4765 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4766 // similar as below.
4767 using namespace clang;
4768 Sema& SemaR = fInterpreter->getSema();
4769 DeclarationName DName = &SemaR.Context.Idents.get(name);
4770
4771 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4772 Sema::ForExternalRedeclaration);
4773
4774 cling::utils::Lookup::Named(&SemaR, R);
4775
4776 LookupResult::Filter F = R.makeFilter();
4777 // Filter the data-member looking decls.
4778 while (F.hasNext()) {
4779 NamedDecl *D = F.next();
4780 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4781 isa<IndirectFieldDecl>(D))
4782 continue;
4783 F.erase();
4784 }
4785 F.done();
4786
4787 if (R.isSingleResult())
4788 return R.getFoundDecl();
4789 return 0;
4790}
4791
4792////////////////////////////////////////////////////////////////////////////////
4793/// Return pointer to cling Decl of global/static variable that is located
4794/// at the address given by addr.
4795
4797{
4799
4800 const clang::Decl* possibleEnum = 0;
4801 // FInd the context of the decl.
4802 if (cl) {
4804 if (cci) {
4805 const clang::DeclContext* dc = 0;
4806 if (const clang::Decl* D = cci->GetDecl()) {
4807 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4808 dc = dyn_cast<clang::RecordDecl>(D);
4809 }
4810 }
4811 if (dc) {
4812 // If it is a data member enum.
4813 // Could trigger deserialization of decls.
4814 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4815 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4816 } else {
4817 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4818 }
4819 }
4820 } else {
4821 // If it is a global enum.
4822 // Could trigger deserialization of decls.
4823 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4824 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4825 }
4826 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4827 && isa<clang::EnumDecl>(possibleEnum)) {
4828 return possibleEnum;
4829 }
4830 return 0;
4831}
4832
4833////////////////////////////////////////////////////////////////////////////////
4834/// Return pointer to cling DeclId for a global value
4835
4836TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4837{
4838 if (!gv) return 0;
4839
4840 llvm::StringRef mangled_name = gv->getName();
4841
4842 int err = 0;
4843 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4844 if (err) {
4845 if (err == -2) {
4846 // It might simply be an unmangled global name.
4847 DeclId_t d;
4849 d = gcl.GetDataMember(mangled_name.str().c_str());
4850 return d;
4851 }
4852 return 0;
4853 }
4854
4855 std::string scopename(demangled_name_c);
4856 free(demangled_name_c);
4857
4858 //
4859 // Separate out the class or namespace part of the
4860 // function name.
4861 //
4862 std::string dataname;
4863
4864 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4865 scopename.erase(0, sizeof("typeinfo for ")-1);
4866 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4867 scopename.erase(0, sizeof("vtable for ")-1);
4868 } else {
4869 // See if it is a function
4870 std::string::size_type pos = scopename.rfind('(');
4871 if (pos != std::string::npos) {
4872 return 0;
4873 }
4874 // Separate the scope and member name
4875 pos = scopename.rfind(':');
4876 if (pos != std::string::npos) {
4877 if ((pos != 0) && (scopename[pos-1] == ':')) {
4878 dataname = scopename.substr(pos+1);
4879 scopename.erase(pos-1);
4880 }
4881 } else {
4882 scopename.clear();
4883 dataname = scopename;
4884 }
4885 }
4886 //fprintf(stderr, "name: '%s'\n", name.c_str());
4887 // Now we have the class or namespace name, so do the lookup.
4888
4889
4890 DeclId_t d;
4891 if (scopename.size()) {
4892 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4893 d = cl.GetDataMember(dataname.c_str());
4894 }
4895 else {
4897 d = gcl.GetDataMember(dataname.c_str());
4898 }
4899 return d;
4900}
4901
4902////////////////////////////////////////////////////////////////////////////////
4903/// NOT IMPLEMENTED.
4904
4906{
4907 Error("GetDataMemberWithValue()", "not implemented");
4908 return 0;
4909}
4910
4911////////////////////////////////////////////////////////////////////////////////
4912/// Return pointer to cling DeclId for a data member with a given name.
4913
4915{
4916 // NOT IMPLEMENTED.
4917 Error("GetDataMemberAtAddr()", "not implemented");
4918 return 0;
4919}
4920
4921////////////////////////////////////////////////////////////////////////////////
4922/// Return the cling mangled name for a method of a class with parameters
4923/// params (params is a string of actual arguments, not formal ones). If the
4924/// class is 0 the global function list will be searched.
4925
4926TString TCling::GetMangledName(TClass* cl, const char* method,
4927 const char* params, Bool_t objectIsConst /* = kFALSE */)
4928{
4931 if (cl) {
4933 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4934 &offset);
4935 }
4936 else {
4939 func.SetFunc(&gcl, method, params, &offset);
4940 }
4942 if (!mi) return "";
4943 TString mangled_name( mi->GetMangledName() );
4944 delete mi;
4945 return mangled_name;
4946}
4947
4948////////////////////////////////////////////////////////////////////////////////
4949/// Return the cling mangled name for a method of a class with a certain
4950/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4951/// list will be searched.
4952
4954 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4955 EFunctionMatchMode mode /* = kConversionMatch */)
4956{
4958 if (cl) {
4959 return ((TClingClassInfo*)cl->GetClassInfo())->
4960 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4961 }
4963 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4964}
4965
4966////////////////////////////////////////////////////////////////////////////////
4967/// Return pointer to cling interface function for a method of a class with
4968/// parameters params (params is a string of actual arguments, not formal
4969/// ones). If the class is 0 the global function list will be searched.
4970
4971void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4972 const char* params, Bool_t objectIsConst /* = kFALSE */)
4973{
4976 if (cl) {
4978 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4979 &offset);
4980 }
4981 else {
4984 func.SetFunc(&gcl, method, params, &offset);
4985 }
4986 return (void*) func.InterfaceMethod();
4987}
4988
4989////////////////////////////////////////////////////////////////////////////////
4990/// Return pointer to cling interface function for a method of a class with
4991/// a certain name.
4992
4993TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4994{
4996 DeclId_t f;
4997 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4998 if (cl) {
4999 f = cl->GetMethod(method).GetDeclId();
5000 }
5001 else {
5003 f = gcl.GetMethod(method).GetDeclId();
5004 }
5005 return f;
5006
5007}
5008
5009////////////////////////////////////////////////////////////////////////////////
5010/// Insert overloads of name in cl to res.
5011
5012void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5013 std::vector<DeclId_t>& res) const
5014{
5015 clang::Sema& S = fInterpreter->getSema();
5016 clang::ASTContext& Ctx = S.Context;
5017 const clang::Decl* CtxDecl
5018 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5019 Ctx.getTranslationUnitDecl();
5020 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5021 const clang::DeclContext* DeclCtx = RecDecl;
5022
5023 if (!DeclCtx)
5024 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5025 if (!DeclCtx) return;
5026
5027 clang::DeclarationName DName;
5028 // The DeclarationName is funcname, unless it's a ctor or dtor.
5029 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5030
5031 if (RecDecl) {
5032 if (RecDecl->getNameAsString() == funcname) {
5033 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5034 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5035 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5036 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5037 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5038 } else {
5039 DName = &Ctx.Idents.get(funcname);
5040 }
5041 } else {
5042 DName = &Ctx.Idents.get(funcname);
5043 }
5044
5045 // NotForRedeclaration: we want to find names in inline namespaces etc.
5046 clang::LookupResult R(S, DName, clang::SourceLocation(),
5047 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5048 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5049 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5050 if (R.empty()) return;
5051 R.resolveKind();
5052 res.reserve(res.size() + (R.end() - R.begin()));
5053 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5054 IR != ER; ++IR) {
5055 if (const clang::FunctionDecl* FD
5056 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5057 if (!FD->getDescribedFunctionTemplate()) {
5058 res.push_back(FD);
5059 }
5060 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5061 // FIXME: multi-level using
5062 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5063 res.push_back(USD);
5064 }
5065 }
5066 }
5067}
5068
5069////////////////////////////////////////////////////////////////////////////////
5070/// Return pointer to cling interface function for a method of a class with
5071/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5072/// function list will be searched.
5073
5075 const char* proto,
5076 Bool_t objectIsConst /* = kFALSE */,
5077 EFunctionMatchMode mode /* = kConversionMatch */)
5078{
5080 void* f;
5081 if (cl) {
5082 f = ((TClingClassInfo*)cl->GetClassInfo())->
5083 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod();
5084 }
5085 else {
5087 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod();
5088 }
5089 return f;
5090}
5091
5092////////////////////////////////////////////////////////////////////////////////
5093/// Return pointer to cling DeclId for a method of a class with
5094/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5095/// function list will be searched.
5096
5097TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5098 const char* params,
5099 Bool_t objectIsConst /* = kFALSE */)
5100{
5102 DeclId_t f;
5103 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5104 if (cl) {
5105 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5106 }
5107 else {
5109 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
5110 }
5111 return f;
5112}
5113
5114////////////////////////////////////////////////////////////////////////////////
5115/// Return pointer to cling interface function for a method of a class with
5116/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5117/// function list will be searched.
5118
5119TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5120 const char* proto,
5121 Bool_t objectIsConst /* = kFALSE */,
5122 EFunctionMatchMode mode /* = kConversionMatch */)
5123{
5125 DeclId_t f;
5126 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5127 if (cl) {
5128 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5129 }
5130 else {
5132 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
5133 }
5134 return f;
5135}
5136
5137////////////////////////////////////////////////////////////////////////////////
5138/// Return pointer to cling interface function for a method of a class with
5139/// a certain name.
5140
5141TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5142{
5144 DeclId_t f;
5145 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5146 if (cl) {
5147 f = cl->GetFunctionTemplate(name);
5148 }
5149 else {
5151 f = gcl.GetFunctionTemplate(name);
5152 }
5153 return f;
5154
5155}
5156
5157////////////////////////////////////////////////////////////////////////////////
5158/// The 'name' is known to the interpreter, this function returns
5159/// the internal version of this name (usually just resolving typedefs)
5160/// This is used in particular to synchronize between the name used
5161/// by rootcling and by the run-time environment (TClass)
5162/// Return 0 if the name is not known.
5163
5164void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5165{
5166 output.clear();
5167
5169
5171 if (!cl.IsValid()) {
5172 return ;
5173 }
5174 if (full) {
5176 return;
5177 }
5178 // Well well well, for backward compatibility we need to act a bit too
5179 // much like CINT.
5182
5183 return;
5184}
5185
5186////////////////////////////////////////////////////////////////////////////////
5187/// Execute a global function with arguments params.
5188///
5189/// FIXME: The cint-based version of this code does not check if the
5190/// SetFunc() call works, and does not do any real checking
5191/// for errors from the Exec() call. It did fetch the most
5192/// recent cint security error and return that in error, but
5193/// this does not really translate well to cling/clang. We
5194/// should enhance these interfaces so that we can report
5195/// compilation and runtime errors properly.
5196
5197void TCling::Execute(const char* function, const char* params, int* error)
5198{
5200 if (error) {
5201 *error = TInterpreter::kNoError;
5202 }
5204 Longptr_t offset = 0L;
5206 func.SetFunc(&cl, function, params, &offset);
5207 func.Exec(0);
5208}
5209
5210////////////////////////////////////////////////////////////////////////////////
5211/// Execute a method from class cl with arguments params.
5212///
5213/// FIXME: The cint-based version of this code does not check if the
5214/// SetFunc() call works, and does not do any real checking
5215/// for errors from the Exec() call. It did fetch the most
5216/// recent cint security error and return that in error, but
5217/// this does not really translate well to cling/clang. We
5218/// should enhance these interfaces so that we can report
5219/// compilation and runtime errors properly.
5220
5221void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5222 const char* params, Bool_t objectIsConst, int* error)
5223{
5225 if (error) {
5226 *error = TInterpreter::kNoError;
5227 }
5228 // If the actual class of this object inherits 2nd (or more) from TObject,
5229 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5230 // hence gInterpreter->Execute will improperly correct the offset.
5231 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5232 Longptr_t offset = 0L;
5234 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5235 void* address = (void*)((Longptr_t)addr + offset);
5236 func.Exec(address);
5237}
5238
5239////////////////////////////////////////////////////////////////////////////////
5240
5241void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5242 const char* params, int* error)
5243{
5244 Execute(obj,cl,method,params,false,error);
5245}
5246
5247////////////////////////////////////////////////////////////////////////////////
5248/// Execute a method from class cl with the arguments in array params
5249/// (params[0] ... params[n] = array of TObjString parameters).
5250/// Convert the TObjArray array of TObjString parameters to a character
5251/// string of comma separated parameters.
5252/// The parameters of type 'char' are enclosed in double quotes and all
5253/// internal quotes are escaped.
5254
5255void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5256 TObjArray* params, int* error)
5257{
5258 if (!method) {
5259 Error("Execute", "No method was defined");
5260 return;
5261 }
5262 TList* argList = method->GetListOfMethodArgs();
5263 // Check number of actual parameters against of expected formal ones
5264
5265 Int_t nparms = argList->LastIndex() + 1;
5266 Int_t argc = params ? params->GetEntries() : 0;
5267
5268 if (argc > nparms) {
5269 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5270 return;
5271 }
5272 if (nparms != argc) {
5273 // Let's see if the 'missing' argument are all defaulted.
5274 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5275 assert(nparms > 0);
5276
5277 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5278 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5279 // There is a default value for the first missing
5280 // argument, so we are fine.
5281 } else {
5282 Int_t firstDefault = -1;
5283 for (Int_t i = 0; i < nparms; i ++) {
5284 arg = (TMethodArg *) argList->At( i );
5285 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5286 firstDefault = i;
5287 break;
5288 }
5289 }
5290 if (firstDefault >= 0) {
5291 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);
5292 } else {
5293 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5294 }
5295 return;
5296 }
5297 }
5298
5299 const char* listpar = "";
5300 TString complete(10);
5301 if (params) {
5302 // Create a character string of parameters from TObjArray
5303 TIter next(params);
5304 for (Int_t i = 0; i < argc; i ++) {
5305 TMethodArg* arg = (TMethodArg*) argList->At(i);
5307 TObjString* nxtpar = (TObjString*) next();
5308 if (i) {
5309 complete += ',';
5310 }
5311 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5312 TString chpar('\"');
5313 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5314 // At this point we have to check if string contains \\"
5315 // and apply some more sophisticated parser. Not implemented yet!
5316 complete += chpar;
5317 complete += '\"';
5318 }
5319 else {
5320 complete += nxtpar->String();
5321 }
5322 }
5323 listpar = complete.Data();
5324 }
5325
5326 // And now execute it.
5328 if (error) {
5329 *error = TInterpreter::kNoError;
5330 }
5331 // If the actual class of this object inherits 2nd (or more) from TObject,
5332 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5333 // hence gInterpreter->Execute will improperly correct the offset.
5334 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5336 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5337 func.Init(*minfo);
5338 func.SetArgs(listpar);
5339 // Now calculate the 'this' pointer offset for the method
5340 // when starting from the class described by cl.
5341 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5342 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5343 void* address = (void*)((Longptr_t)addr + offset);
5344 func.Exec(address);
5345}
5346
5347////////////////////////////////////////////////////////////////////////////////
5348
5349void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5350 const void* args[] /*=0*/,
5351 int nargs /*=0*/,
5352 void* ret/*= 0*/) const
5353{
5354 if (!method) {
5355 Error("ExecuteWithArgsAndReturn", "No method was defined");
5356 return;
5357 }
5358
5359 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5360 TClingCallFunc func(*minfo);
5361 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5362}
5363
5364////////////////////////////////////////////////////////////////////////////////
5365/// Execute a cling macro.
5366
5368{
5370 fCurExecutingMacros.push_back(filename);
5372 fCurExecutingMacros.pop_back();
5373 return result;
5374}
5375
5376////////////////////////////////////////////////////////////////////////////////
5377/// Return the file name of the current un-included interpreted file.
5378/// See the documentation for GetCurrentMacroName().
5379
5381{
5382 Warning("GetTopLevelMacroName", "Must change return type!");
5383 return fCurExecutingMacros.back();
5384}
5385
5386////////////////////////////////////////////////////////////////////////////////
5387/// Return the file name of the currently interpreted file,
5388/// included or not. Example to illustrate the difference between
5389/// GetCurrentMacroName() and GetTopLevelMacroName():
5390/// ~~~ {.cpp}
5391/// void inclfile() {
5392/// std::cout << "In inclfile.C" << std::endl;
5393/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5394/// TCling::GetCurrentMacroName() << std::endl;
5395/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5396/// TCling::GetTopLevelMacroName() << std::endl;
5397/// }
5398/// ~~~
5399/// ~~~ {.cpp}
5400/// void mymacro() {
5401/// std::cout << "In mymacro.C" << std::endl;
5402/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5403/// TCling::GetCurrentMacroName() << std::endl;
5404/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5405/// TCling::GetTopLevelMacroName() << std::endl;
5406/// std::cout << " Now calling inclfile..." << std::endl;
5407/// gInterpreter->ProcessLine(".x inclfile.C");;
5408/// }
5409/// ~~~
5410/// Running mymacro.C will print:
5411///
5412/// ~~~ {.cpp}
5413/// root [0] .x mymacro.C
5414/// ~~~
5415/// In mymacro.C
5416/// ~~~ {.cpp}
5417/// TCling::GetCurrentMacroName() returns ./mymacro.C
5418/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5419/// ~~~
5420/// Now calling inclfile...
5421/// In inclfile.h
5422/// ~~~ {.cpp}
5423/// TCling::GetCurrentMacroName() returns inclfile.C
5424/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5425/// ~~~
5426
5428{
5429#if defined(R__MUST_REVISIT)
5430#if R__MUST_REVISIT(6,0)
5431 Warning("GetCurrentMacroName", "Must change return type!");
5432#endif
5433#endif
5434 return fCurExecutingMacros.back();
5435}
5436
5437////////////////////////////////////////////////////////////////////////////////
5438/// Return the absolute type of typeDesc.
5439/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5440/// You need to use the result immediately before it is being overwritten.
5441
5442const char* TCling::TypeName(const char* typeDesc)
5443{
5444 TTHREAD_TLS_DECL(std::string,t);
5445
5446 if (!strstr(typeDesc, "(*)(")) {
5447 const char *s = strchr(typeDesc, ' ');
5448 const char *template_start = strchr(typeDesc, '<');
5449 if (!strcmp(typeDesc, "long long")) {
5450 t = typeDesc;
5451 }
5452 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5453 t = typeDesc;
5454 }
5455 // s is the position of the second 'word' (if any)
5456 // except in the case of templates where there will be a space
5457 // just before any closing '>': eg.
5458 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5459 else if (s && (template_start == 0 || (s < template_start))) {
5460 t = s + 1;
5461 }
5462 else {
5463 t = typeDesc;
5464 }
5465 }
5466 else {
5467 t = typeDesc;
5468 }
5469 auto l = t.length();
5470 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5471 --l;
5472 t.resize(l);
5473 return t.c_str(); // NOLINT
5474}
5475
5476static bool requiresRootMap(const char* rootmapfile)
5477{
5478 assert(rootmapfile && *rootmapfile);
5479
5480 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5481 libName.consume_back(".rootmap");
5482
5483 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5484}
5485
5486////////////////////////////////////////////////////////////////////////////////
5487/// Read and parse a rootmapfile in its new format, and return 0 in case of
5488/// success, -1 if the file has already been read, and -3 in case its format
5489/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5490/// error.
5491
5492int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5493{
5494 if (!(rootmapfile && *rootmapfile))
5495 return 0;
5496
5497 if (!requiresRootMap(rootmapfile))
5498 return 0; // success
5499
5500 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5501 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5502
5503 std::string rootmapfileNoBackslash(rootmapfile);
5504#ifdef _MSC_VER
5505 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5506#endif
5507 // Add content of a specific rootmap file
5508 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5509 return -1;
5510
5511 // Line 1 is `{ decls }`
5512 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5513
5514 std::ifstream file(rootmapfileNoBackslash);
5515 std::string line;
5516 line.reserve(200);
5517 std::string lib_name;
5518 line.reserve(100);
5519 bool newFormat = false;
5520 while (getline(file, line, '\n')) {
5521 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5522 file.close();
5523 return -3; // old format
5524 }
5525 newFormat = true;
5526
5527 if (line.compare(0, 9, "{ decls }") == 0) {
5528 // forward declarations
5529
5530 while (getline(file, line, '\n')) {
5531 if (line[0] == '[')
5532 break;
5533 if (!uniqueString) {
5534 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5535 rootmapfileNoBackslash.c_str());
5536 return -4;
5537 }
5538 if (!lineDirective.empty())
5539 uniqueString->Append(lineDirective);
5540 uniqueString->Append(line + '\n');
5541 }
5542 }
5543 const char firstChar = line[0];
5544 if (firstChar == '[') {
5545 // new section (library)
5546 auto brpos = line.find(']');
5547 if (brpos == string::npos)
5548 continue;
5549 lib_name = line.substr(1, brpos - 1);
5550 size_t nspaces = 0;
5551 while (lib_name[nspaces] == ' ')
5552 ++nspaces;
5553 if (nspaces)
5554 lib_name.replace(0, nspaces, "");
5555 if (gDebug > 3) {
5556 TString lib_nameTstr(lib_name.c_str());
5557 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5558 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5559 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5560 if (wlib) {
5561 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5562 } else {
5563 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5564 }
5565 delete[] wlib;
5566 delete tokens;
5567 }
5568 } else {
5569 auto keyLenIt = keyLenMap.find(firstChar);
5570 if (keyLenIt == keyLenMap.end())
5571 continue;
5572 unsigned int keyLen = keyLenIt->second;
5573 // Do not make a copy, just start after the key
5574 const char *keyname = line.c_str() + keyLen;
5575 if (gDebug > 6)
5576 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5577 TEnvRec *isThere = fMapfile->Lookup(keyname);
5578 if (isThere) {
5579 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5580 if (firstChar == 'n') {
5581 if (gDebug > 3)
5582 Info("ReadRootmapFile", "namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5583 isThere->GetValue());
5584 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5585 lib_name += " ";
5586 lib_name += isThere->GetValue();
5587 fMapfile->SetValue(keyname, lib_name.c_str());
5588 } else if (!TClassEdit::IsSTLCont(keyname)) {
5589 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5590 keyname, lib_name.c_str(), isThere->GetValue());
5591 }
5592 } else { // the same key for the same lib
5593 if (gDebug > 3)
5594 Info("ReadRootmapFile", "Key %s was already defined for %s", keyname, lib_name.c_str());
5595 }
5596 } else {
5597 fMapfile->SetValue(keyname, lib_name.c_str());
5598 }
5599 }
5600 }
5601 file.close();
5602 return 0;
5603}
5604
5605////////////////////////////////////////////////////////////////////////////////
5606/// Create a resource table and read the (possibly) three resource files,
5607/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5608/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5609/// can read additional user defined resource files by creating additional TEnv
5610/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5611/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5612/// case the home directory resides on an automounted remote file system
5613/// and one wants to avoid the file system from being mounted.
5614
5616{
5617 assert(requiresRootMap(name) && "We have a module!");
5618
5619 if (!requiresRootMap(name))
5620 return;
5621
5623
5625
5626 TString sname = "system";
5627 sname += name;
5628 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5629
5630 Int_t ret = ReadRootmapFile(s);
5631 if (ret == -3) // old format
5633 delete [] s;
5634 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5636 ret = ReadRootmapFile(s);
5637 if (ret == -3) // old format
5639 delete [] s;
5640 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5641 ret = ReadRootmapFile(name);
5642 if (ret == -3) // old format
5644 }
5645 } else {
5646 ret = ReadRootmapFile(name);
5647 if (ret == -3) // old format
5649 }
5650 fMapfile->IgnoreDuplicates(ignore);
5651}
5652
5653
5654namespace {
5655 using namespace clang;
5656
5657 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5658 // This class is to be considered an helper for AutoLoading.
5659 // It is a recursive visitor is used to inspect namespaces and specializations
5660 // coming from forward declarations in rootmaps and to set the external visible
5661 // storage flag for them.
5662 public:
5663 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5664 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5665 // We want to enable the external lookup for this namespace
5666 // because it may shadow the lookup of other names contained
5667 // in that namespace
5668
5669 nsDecl->setHasExternalVisibleStorage();
5670 fNSSet.insert(nsDecl);
5671 return true;
5672 }
5673 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5674 // We want to enable the external lookup for this specialization
5675 // because we can provide a definition for it!
5676 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5677 //SpecSet.insert(specDecl);
5678 specDecl->setHasExternalLexicalStorage();
5679
5680 // No need to recurse. On the contrary, recursing is actively harmful:
5681 // NOTE: must not recurse to prevent this visitor from triggering loading from
5682 // the external AST source (i.e. autoloading). This would be triggered right here,
5683 // before autoloading is even set up, as rootmap file parsing happens before that.
5684 // Even if autoloading is off and has no effect, triggering loading from external
5685 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5686 // from subsequent autoloads!
5687 return false;
5688 }
5689 private:
5690 std::unordered_set<const NamespaceDecl*>& fNSSet;
5691 };
5692}
5693
5694////////////////////////////////////////////////////////////////////////////////
5695/// Load map between class and library. If rootmapfile is specified a
5696/// specific rootmap file can be added (typically used by ACLiC).
5697/// In case of error -1 is returned, 0 otherwise.
5698/// The interpreter uses this information to automatically load the shared
5699/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5700
5701Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5702{
5703 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5704 return 0;
5705
5707
5708 // open the [system].rootmap files
5709 if (!fMapfile) {
5710 fMapfile = new TEnv();
5714 InitRootmapFile(".rootmap");
5715 }
5716
5717 // Prepare a list of all forward declarations for cling
5718 // For some experiments it is easily as big as 500k characters. To be on the
5719 // safe side, we go for 1M.
5720 TUniqueString uniqueString(1048576);
5721
5722 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5723 // A rootmap file must end with the string ".rootmap".
5724 TString ldpath = gSystem->GetDynamicPath();
5725 if (ldpath != fRootmapLoadPath) {
5726 fRootmapLoadPath = ldpath;
5727#ifdef WIN32
5728 TObjArray* paths = ldpath.Tokenize(";");
5729#else
5730 TObjArray* paths = ldpath.Tokenize(":");
5731#endif
5732 TString d;
5733 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5734 d = ((TObjString *)paths->At(i))->GetString();
5735 // check if directory already scanned
5736 Int_t skip = 0;
5737 for (Int_t j = 0; j < i; j++) {
5738 TString pd = ((TObjString *)paths->At(j))->GetString();
5739 if (pd == d) {
5740 skip++;
5741 break;
5742 }
5743 }
5744 if (!skip) {
5745 void* dirp = gSystem->OpenDirectory(d);
5746 if (dirp) {
5747 if (gDebug > 3) {
5748 Info("LoadLibraryMap", "%s", d.Data());
5749 }
5750 const char* f1;
5751 while ((f1 = gSystem->GetDirEntry(dirp))) {
5752 TString f = f1;
5753 if (f.EndsWith(".rootmap")) {
5754 TString p;
5755 p = d + "/" + f;
5757 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5758 if (gDebug > 4) {
5759 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5760 }
5761 Int_t ret = ReadRootmapFile(p, &uniqueString);
5762
5763 if (ret == 0)
5764 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5765 if (ret == -3) {
5766 // old format
5768 fRootmapFiles->Add(new TNamed(f, p));
5769 }
5770 }
5771 // else {
5772 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5773 // fRootmapFiles->FindObject(f)->ls();
5774 // }
5775 }
5776 }
5777 if (f.BeginsWith("rootmap")) {
5778 TString p;
5779 p = d + "/" + f;
5780 FileStat_t stat;
5781 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5782 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5783 }
5784 }
5785 }
5786 }
5787 gSystem->FreeDirectory(dirp);
5788 }
5789 }
5790 delete paths;
5791 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5792 return -1;
5793 }
5794 }
5795 if (rootmapfile && *rootmapfile) {
5796 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5797 if (res == 0) {
5798 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5799 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5800 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5801 }
5802 else if (res == -3) {
5803 // old format
5805 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5806 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5807 fMapfile->IgnoreDuplicates(ignore);
5808 }
5809 }
5810 TEnvRec* rec;
5811 TIter next(fMapfile->GetTable());
5812 while ((rec = (TEnvRec*) next())) {
5813 TString cls = rec->GetName();
5814 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5815 // get the first lib from the list of lib and dependent libs
5816 TString libs = rec->GetValue();
5817 if (libs == "") {
5818 continue;
5819 }
5820 TString delim(" ");
5821 TObjArray* tokens = libs.Tokenize(delim);
5822 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5823 // convert "@@" to "::", we used "@@" because TEnv
5824 // considers "::" a terminator
5825 cls.Remove(0, 8);
5826 cls.ReplaceAll("@@", "::");
5827 // convert "-" to " ", since class names may have
5828 // blanks and TEnv considers a blank a terminator
5829 cls.ReplaceAll("-", " ");
5830 if (gDebug > 6) {
5831 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5832 if (wlib) {
5833 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5834 }
5835 else {
5836 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5837 }
5838 delete[] wlib;
5839 }
5840 delete tokens;
5841 }
5842 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5843 cls.Remove(0, 8);
5844 // convert "-" to " ", since class names may have
5845 // blanks and TEnv considers a blank a terminator
5846 cls.ReplaceAll("-", " ");
5847 fInterpreter->declare(cls.Data());
5848 }
5849 }
5850
5851 // Process the forward declarations collected
5852 cling::Transaction* T = nullptr;
5853 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5854 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5855
5856 if (compRes!=cling::Interpreter::kSuccess){
5857 Warning("LoadLibraryMap",
5858 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5859 }
5860
5861 if (T) {
5862 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5863 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5864 if (declIt->m_DGR.isSingleDecl()) {
5865 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5866 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5867 evsAdder.TraverseDecl(D);
5868 }
5869 }
5870 }
5871 }
5872 }
5873
5874 // clear duplicates
5875
5876 return 0;
5877}
5878
5879////////////////////////////////////////////////////////////////////////////////
5880/// Scan again along the dynamic path for library maps. Entries for the loaded
5881/// shared libraries are unloaded first. This can be useful after reseting
5882/// the dynamic path through TSystem::SetDynamicPath()
5883/// In case of error -1 is returned, 0 otherwise.
5884
5886{
5889 return 0;
5890}
5891
5892////////////////////////////////////////////////////////////////////////////////
5893/// Reload the library map entries coming from all the loaded shared libraries,
5894/// after first unloading the current ones.
5895/// In case of error -1 is returned, 0 otherwise.
5896
5898{
5899 const TString sharedLibLStr = GetSharedLibs();
5900 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5901 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5902 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5903 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5904 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5905 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5906 if (ret < 0) {
5907 continue;
5908 }
5909 TString rootMapBaseStr = sharedLibBaseStr;
5910 if (sharedLibBaseStr.EndsWith(".dll")) {
5911 rootMapBaseStr.ReplaceAll(".dll", "");
5912 }
5913 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5914 rootMapBaseStr.ReplaceAll(".DLL", "");
5915 }
5916 else if (sharedLibBaseStr.EndsWith(".so")) {
5917 rootMapBaseStr.ReplaceAll(".so", "");
5918 }
5919 else if (sharedLibBaseStr.EndsWith(".sl")) {
5920 rootMapBaseStr.ReplaceAll(".sl", "");
5921 }
5922 else if (sharedLibBaseStr.EndsWith(".dl")) {
5923 rootMapBaseStr.ReplaceAll(".dl", "");
5924 }
5925 else if (sharedLibBaseStr.EndsWith(".a")) {
5926 rootMapBaseStr.ReplaceAll(".a", "");
5927 }
5928 else {
5929 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5930 delete sharedLibL;
5931 return -1;
5932 }
5933 rootMapBaseStr += ".rootmap";
5934 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5935 if (!rootMap) {
5936 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5937 delete[] rootMap;
5938 delete sharedLibL;
5939 return -1;
5940 }
5941 const Int_t status = LoadLibraryMap(rootMap);
5942 if (status < 0) {
5943 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5944 delete[] rootMap;
5945 delete sharedLibL;
5946 return -1;
5947 }
5948 delete[] rootMap;
5949 }
5950 delete sharedLibL;
5951 return 0;
5952}
5953
5954////////////////////////////////////////////////////////////////////////////////
5955/// Unload the library map entries coming from all the loaded shared libraries.
5956/// Returns 0 if succesful
5957
5959{
5960 const TString sharedLibLStr = GetSharedLibs();
5961 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5962 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5963 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5964 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5965 UnloadLibraryMap(sharedLibBaseStr);
5966 }
5967 delete sharedLibL;
5968 return 0;
5969}
5970
5971////////////////////////////////////////////////////////////////////////////////
5972/// Unload library map entries coming from the specified library.
5973/// Returns -1 in case no entries for the specified library were found,
5974/// 0 otherwise.
5975
5977{
5978 if (!fMapfile || !library || !*library) {
5979 return 0;
5980 }
5981 TString libname(library);
5982 Ssiz_t idx = libname.Last('.');
5983 if (idx != kNPOS) {
5984 libname.Remove(idx);
5985 }
5986 size_t len = libname.Length();
5987 TEnvRec *rec;
5988 TIter next(fMapfile->GetTable());
5990 Int_t ret = 0;
5991 while ((rec = (TEnvRec *) next())) {
5992 TString cls = rec->GetName();
5993 if (cls.Length() > 2) {
5994 // get the first lib from the list of lib and dependent libs
5995 TString libs = rec->GetValue();
5996 if (libs == "") {
5997 continue;
5998 }
5999 TString delim(" ");
6000 TObjArray* tokens = libs.Tokenize(delim);
6001 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6002 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6003 // convert "@@" to "::", we used "@@" because TEnv
6004 // considers "::" a terminator
6005 cls.Remove(0, 8);
6006 cls.ReplaceAll("@@", "::");
6007 // convert "-" to " ", since class names may have
6008 // blanks and TEnv considers a blank a terminator
6009 cls.ReplaceAll("-", " ");
6010 }
6011 if (!strncmp(lib, libname.Data(), len)) {
6012 if (fMapfile->GetTable()->Remove(rec) == 0) {
6013 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6014 ret = -1;
6015 }
6016 }
6017 delete tokens;
6018 }
6019 }
6020 if (ret >= 0) {
6021 TString library_rootmap(library);
6022 if (!library_rootmap.EndsWith(".rootmap"))
6023 library_rootmap.Append(".rootmap");
6024 TNamed* mfile = 0;
6025 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6026 fRootmapFiles->Remove(mfile);
6027 delete mfile;
6028 }
6030 }
6031 return ret;
6032}
6033
6034////////////////////////////////////////////////////////////////////////////////
6035/// Register the AutoLoading information for a class.
6036/// libs is a space separated list of libraries.
6037
6038Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6039{
6040 if (!cls || !*cls)
6041 return 0;
6042
6043 TString key = TString("Library.") + cls;
6044 // convert "::" to "@@", we used "@@" because TEnv
6045 // considers "::" a terminator
6046 key.ReplaceAll("::", "@@");
6047 // convert "-" to " ", since class names may have
6048 // blanks and TEnv considers a blank a terminator
6049 key.ReplaceAll(" ", "-");
6050
6052 if (!fMapfile) {
6053 fMapfile = new TEnv();
6055
6058
6059 InitRootmapFile(".rootmap");
6060 }
6061 //fMapfile->SetValue(key, libs);
6062 fMapfile->SetValue(cls, libs);
6063 return 1;
6064}
6065
6066////////////////////////////////////////////////////////////////////////////////
6067/// Demangle the name (from the typeinfo) and then request the class
6068/// via the usual name based interface (TClass::GetClass).
6069
6070TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6071{
6072 int err = 0;
6073 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6074 if (err) return 0;
6075 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6076 free(demangled_name);
6077 return theClass;
6078}
6079
6080////////////////////////////////////////////////////////////////////////////////
6081/// Load library containing the specified class. Returns 0 in case of error
6082/// and 1 in case if success.
6083
6084Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6085{
6086 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6087
6088 int err = 0;
6089 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6090 if (err) {
6091 return 0;
6092 }
6093
6094 std::string demangled_name(demangled_name_c);
6095 free(demangled_name_c);
6096
6097 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6098 // shortened name.
6100 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6101
6102 // No need to worry about typedef, they aren't any ... but there are
6103 // inlined namespaces ...
6104
6105 Int_t result = AutoLoad(demangled_name.c_str());
6106 if (result == 0) {
6107 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6108 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6109 }
6110
6111 return result;
6112}
6113
6114////////////////////////////////////////////////////////////////////////////////
6115// Get the list of 'published'/'known' library for the class and load them.
6117{
6118 Int_t status = 0;
6119
6120 // lookup class to find list of dependent libraries
6121 TString deplibs = gCling->GetClassSharedLibs(cls);
6122 if (!deplibs.IsNull()) {
6123 TString delim(" ");
6124 TObjArray* tokens = deplibs.Tokenize(delim);
6125 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6126 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6127 if (gROOT->LoadClass(cls, deplib) == 0) {
6128 if (gDebug > 0) {
6129 gCling->Info("TCling::AutoLoad",
6130 "loaded dependent library %s for %s", deplib, cls);
6131 }
6132 }
6133 else {
6134 gCling->Error("TCling::AutoLoad",
6135 "failure loading dependent library %s for %s",
6136 deplib, cls);
6137 }
6138 }
6139 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6140 if (lib && lib[0]) {
6141 if (gROOT->LoadClass(cls, lib) == 0) {
6142 if (gDebug > 0) {
6143 gCling->Info("TCling::AutoLoad",
6144 "loaded library %s for %s", lib, cls);
6145 }
6146 status = 1;
6147 }
6148 else {
6149 gCling->Error("TCling::AutoLoad",
6150 "failure loading library %s for %s", lib, cls);
6151 }
6152 }
6153 delete tokens;
6154 }
6155
6156 return status;
6157}
6158
6159////////////////////////////////////////////////////////////////////////////////
6160// Iterate through the data member of the class (either through the TProtoClass
6161// or through Cling) and trigger, recursively, the loading the necessary libraries.
6162// \note `cls` is expected to be already normalized!
6163// \returns 1 on success.
6164Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6165 bool nameIsNormalized)
6166{
6167 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6168 // has previously (within the same call to `AutoLoad()`) tried to load this class
6169 // and we are done, whether success or not, as it won't work better now than before,
6170 // because there is no additional information now compared to before.
6171 if (!visited.insert(std::string(cls)).second)
6172 return 1;
6173
6174 if (ShallowAutoLoadImpl(cls) == 0) {
6175 // If ShallowAutoLoadImpl() has an error, we have an error.
6176 return 0;
6177 }
6178
6179 // Now look through the TProtoClass to load the required library/dictionary
6180 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6181 for (auto element : proto->GetData()) {
6182 if (element->IsBasic())
6183 continue;
6184 const char *subtypename = element->GetTypeName();
6185 if (!TClassTable::GetDictNorm(subtypename)) {
6186 // Failure to load a dictionary is not (quite) a failure load
6187 // the top-level library. If we return false here, then
6188 // we would end up in a situation where the library and thus
6189 // the dictionary is loaded for "cls" but the TClass is
6190 // not created and/or marked as unavailable (in case where
6191 // AutoLoad is called from TClass::GetClass).
6192 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6193 }
6194 }
6195 return 1;
6196 }
6197
6198 // We found no TProtoClass for cls.
6199 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6200 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6201 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6202 {
6203 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6204 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6205 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6206 continue;
6207 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6208 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6209 // Failure to load a dictionary is not (quite) a failure load
6210 // the top-level library. See detailed comment in the TProtoClass
6211 // branch (above).
6212 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6213 }
6214 }
6215 gInterpreter->DataMemberInfo_Delete(memberinfo);
6216 }
6217 gInterpreter->ClassInfo_Delete(classinfo);
6218 return 1;
6219}
6220
6221////////////////////////////////////////////////////////////////////////////////
6222/// Load library containing the specified class. Returns 0 in case of error
6223/// and 1 in case if success.
6224
6225Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6226{
6227 // Prevent update to IsClassAutoloading between our check and our actions.
6229
6230 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6231 // rootcling (in *_rdict.pcm file generation) it is a no op.
6232 // FIXME: We should avoid calling autoload when we know we are not supposed
6233 // to and transform this check into an assert.
6235 // Never load any library from rootcling/genreflex.
6236 if (gDebug > 2) {
6237 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6238 }
6239 return 0;
6240 }
6241
6242 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6243
6245
6246 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6247 // The library is already loaded as the class's dictionary is known.
6248 // Return success.
6249 // Note: the name (cls) is expected to be normalized as it comes either
6250 // from a callbacks (that can/should calculate the normalized name from the
6251 // decl) or from TClass::GetClass (which does also calculate the normalized
6252 // name).
6253 return 1;
6254 }
6255
6256 if (gDebug > 2) {
6257 Info("TCling::AutoLoad",
6258 "Trying to autoload for %s", cls);
6259 }
6260
6261 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6262 if (gDebug > 2) {
6263 Info("TCling::AutoLoad",
6264 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6265 }
6266 return 0;
6267 }
6268 // Prevent the recursion when the library dictionary are loaded.
6269 SuspendAutoLoadingRAII autoLoadOff(this);
6270 // Try using externally provided callback first.
6271 if (fAutoLoadCallBack) {
6272 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6273 if (success)
6274 return success;
6275 }
6276
6277 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6278 // (when module are enabled) which might end up calling AutoParsing but
6279 // that should only be for the cases where the library has no generated pcm
6280 // and in that case a rootmap should be available.
6281 // This avoids a very costly operation (for generally no gain) but reduce the
6282 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6283 // file).
6284 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6285 std::unordered_set<std::string> visited;
6286 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6287}
6288
6289////////////////////////////////////////////////////////////////////////////////
6290/// Parse the payload or header.
6291
6292static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6293 Bool_t header,
6294 cling::Interpreter *interpreter)
6295{
6296 std::string code = gNonInterpreterClassDef ;
6297 if (!header) {
6298 // This is the complete header file content and not the
6299 // name of a header.
6300 code += what;
6301
6302 } else {
6303 code += ("#include \"");
6304 code += what;
6305 code += "\"\n";
6306 }
6307 code += ("#ifdef __ROOTCLING__\n"
6308 "#undef __ROOTCLING__\n"
6309 + gInterpreterClassDef +
6310 "#endif");
6311
6312 cling::Interpreter::CompilationResult cr;
6313 {
6314 // scope within which diagnostics are de-activated
6315 // For now we disable diagnostics because we saw them already at
6316 // dictionary generation time. That won't be an issue with the PCMs.
6317
6318 Sema &SemaR = interpreter->getSema();
6319 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6320 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6321
6322 #if defined(R__MUST_REVISIT)
6323 #if R__MUST_REVISIT(6,2)
6324 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6325 #endif
6326 #endif
6327
6328 cr = interpreter->parseForModule(code);
6329 }
6330 return cr;
6331}
6332
6333////////////////////////////////////////////////////////////////////////////////
6334/// Helper routine for TCling::AutoParse implementing the actual call to the
6335/// parser and looping over template parameters (if
6336/// any) and when they don't have a registered header to autoparse,
6337/// recurse over their template parameters.
6338///
6339/// Returns the number of header parsed.
6340
6341UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6342{
6343 // We assume the lock has already been taken.
6344 // R__LOCKGUARD(gInterpreterMutex);
6345
6346 Int_t nHheadersParsed = 0;
6347 unsigned long offset = 0;
6348 if (strncmp(cls, "const ", 6) == 0) {
6349 offset = 6;
6350 }
6351
6352 // Loop on the possible autoparse keys
6353 bool skipFirstEntry = false;
6354 std::vector<std::string> autoparseKeys;
6355 if (strchr(cls, '<')) {
6356 int nestedLoc = 0;
6357 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6358 // Check if we can skip the name of the template in the autoparses
6359 // Take all the scopes one by one. If all of them are in the AST, we do not
6360 // need to autoparse for that particular template.
6361 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6362 // autoparseKeys[0] is empty when the input is not a template instance.
6363 // The case strchr(cls, '<') != 0 but still not a template instance can
6364 // happens 'just' for string (GetSplit replaces the template by the short name
6365 // and then use that for thew splitting)
6366 TString templateName(autoparseKeys[0]);
6367 auto tokens = templateName.Tokenize("::");
6368 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6369 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6370 if (TClassEdit::IsStdClass(cls + offset))
6371 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6372 auto nTokens = tokens->GetEntriesFast();
6373 for (Int_t tk = 0; tk < nTokens; ++tk) {
6374 auto scopeObj = tokens->UncheckedAt(tk);
6375 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6376 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6377 // Check if we have multiple nodes in the AST with this name
6378 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6379 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6380 if (!previousScopeAsContext) break; // this is not a context
6381 }
6382 delete tokens;
6383 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6384 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6385 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6386 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6387 skipFirstEntry = templatedDecl->hasDefinition();
6388 }
6389 }
6390 }
6391
6392 }
6393 }
6394 if (topLevel) autoparseKeys.emplace_back(cls);
6395
6396 for (const auto & apKeyStr : autoparseKeys) {
6397 if (skipFirstEntry) {
6398 skipFirstEntry=false;
6399 continue;
6400 }
6401 if (apKeyStr.empty()) continue;
6402 const char *apKey = apKeyStr.c_str();
6403 std::size_t normNameHash(fStringHashFunction(apKey));
6404 // If the class was not looked up
6405 if (gDebug > 1) {
6406 Info("TCling::AutoParse",
6407 "Starting autoparse for %s\n", apKey);
6408 }
6409 if (fLookedUpClasses.insert(normNameHash).second) {
6410 auto const &iter = fClassesHeadersMap.find(normNameHash);
6411 if (iter != fClassesHeadersMap.end()) {
6412 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6413 fTransactionHeadersMap.insert({T,normNameHash});
6414 auto const &hNamesPtrs = iter->second;
6415 if (gDebug > 1) {
6416 Info("TCling::AutoParse",
6417 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6418 }
6419 for (auto & hName : hNamesPtrs) {
6420 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6421 if (0 != fPayloads.count(normNameHash)) {
6422 float initRSSval=0.f, initVSIZEval=0.f;
6423 (void) initRSSval; // Avoid unused var warning
6424 (void) initVSIZEval;
6425 if (gDebug > 0) {
6426 Info("AutoParse",
6427 "Parsing full payload for %s", apKey);
6428 ProcInfo_t info;
6429 gSystem->GetProcInfo(&info);
6430 initRSSval = 1e-3*info.fMemResident;
6431 initVSIZEval = 1e-3*info.fMemVirtual;
6432 }
6433 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6434 if (cRes != cling::Interpreter::kSuccess) {
6435 if (hName[0] == '\n')
6436 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6437 } else {
6438 fParsedPayloadsAddresses.insert(hName);
6439 nHheadersParsed++;
6440 if (gDebug > 0){
6441 ProcInfo_t info;
6442 gSystem->GetProcInfo(&info);
6443 float endRSSval = 1e-3*info.fMemResident;
6444 float endVSIZEval = 1e-3*info.fMemVirtual;
6445 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6446 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6447 }
6448 }
6449 } else if (!IsLoaded(hName)) {
6450 if (gDebug > 0) {
6451 Info("AutoParse",
6452 "Parsing single header %s", hName);
6453 }
6454 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6455 if (cRes != cling::Interpreter::kSuccess) {
6456 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6457 } else {
6458 nHheadersParsed++;
6459 }
6460 }
6461 }
6462 }
6463 else {
6464 // There is no header registered for this class, if this a
6465 // template, it will be instantiated if/when it is requested
6466 // and if we do no load/parse its components we might end up
6467 // not using an eventual specialization.
6468 if (strchr(apKey, '<')) {
6469 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6470 }
6471 }
6472 }
6473 }
6474
6475 return nHheadersParsed;
6476
6477}
6478
6479////////////////////////////////////////////////////////////////////////////////
6480/// Parse the headers relative to the class
6481/// Returns 1 in case of success, 0 in case of failure
6482
6483Int_t TCling::AutoParse(const char *cls)
6484{
6485 if (llvm::StringRef(cls).contains("(lambda)"))
6486 return 0;
6487
6490 return AutoLoad(cls);
6491 } else {
6492 return 0;
6493 }
6494 }
6495
6497
6498 if (gDebug > 1) {
6499 Info("TCling::AutoParse",
6500 "Trying to autoparse for %s", cls);
6501 }
6502
6503 // The catalogue of headers is in the dictionary
6505 && !gClassTable->GetDictNorm(cls)) {
6506 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6507 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6508 fInterpreter->getSema());
6509 AutoLoad(cls, true /*knowDictNotLoaded*/);
6510 }
6511
6512 // Prevent the recursion when the library dictionary are loaded.
6513 SuspendAutoLoadingRAII autoLoadOff(this);
6514
6515 // No recursive header parsing on demand; we require headers to be standalone.
6516 SuspendAutoParsing autoParseRAII(this);
6517
6518 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6519
6521
6522 return nHheadersParsed > 0 ? 1 : 0;
6523}
6524
6525// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6526// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6527// false if not.
6528bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6529{
6530 StringRef errMsg(errmessage);
6531 if (errMsg.contains("undefined symbol: ")) {
6532 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6533 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6534 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6535 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6536 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6537 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6538 return true;
6539 } else {
6540 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6541 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6542 return true;
6543 }
6544
6545 return false;
6546}
6547
6548////////////////////////////////////////////////////////////////////////////////
6549/// Autoload a library based on a missing symbol.
6550
6551void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6552 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6553
6554 // We have already loaded the library.
6555 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6556 return Addr;
6557
6558 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6560
6561 auto LibLoader = [](const std::string& LibName) -> bool {
6562 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6563 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6564 "Failed to load library %s", LibName.c_str());
6565 return false;
6566 }
6567 return true; //success.
6568 };
6569
6570 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6571 /*searchSystem=*/ true);
6572
6573 assert(!llvm::StringRef(libName).startswith("libNew") &&
6574 "We must not resolve symbols from libNew!");
6575
6576 if (libName.empty())
6577 return nullptr;
6578
6579 if (!LibLoader(libName))
6580 return nullptr;
6581
6582 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6583}
6584
6585////////////////////////////////////////////////////////////////////////////////
6586
6587Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6588{
6589 return fNSFromRootmaps.count(nsDecl) != 0;
6590}
6591
6592////////////////////////////////////////////////////////////////////////////////
6593/// Internal function. Actually do the update of the ClassInfo when seeing
6594// new TagDecl or NamespaceDecl.
6595void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6596{
6597
6599 if (cci) {
6600 // If we only had a forward declaration then update the
6601 // TClingClassInfo with the definition if we have it now.
6602 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6603 if (!oldDef || (def && def != oldDef)) {
6604 cl->ResetCaches();
6606 if (def) {
6607 // It's a tag decl, not a namespace decl.
6608 cci->Init(*cci->GetType());
6610 }
6611 }
6612 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6613 cl->ResetCaches();
6614 // yes, this is almost a waste of time, but we do need to lookup
6615 // the 'type' corresponding to the TClass anyway in order to
6616 // preserve the opaque typedefs (Double32_t)
6617 if (!alias && def != nullptr)
6618 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6619 else
6620 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6621 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6622 // We now need to update the state and bits.
6623 if (cl->fState != TClass::kHasTClassInit) {
6624 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6627 }
6628 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6629 } else {
6630 delete ((TClingClassInfo *)cl->fClassInfo);
6631 cl->fClassInfo = nullptr;
6632 }
6633 }
6634}
6635
6636////////////////////////////////////////////////////////////////////////////////
6637/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6638void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6639{
6640 const TagDecl *td = dyn_cast<TagDecl>(ND);
6641 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6642 const NamedDecl *canon = nullptr;
6643
6644 std::string name;
6645 TagDecl* tdDef = 0;
6646 if (td) {
6647 canon = tdDef = td->getDefinition();
6648 // Let's pass the decl to the TClass only if it has a definition.
6649 if (!tdDef) return;
6650
6651 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6652 // Ignore incomplete definition.
6653 // Ignore declaration within a function.
6654 return;
6655 }
6656
6657 auto declName = tdDef->getNameAsString();
6658 // Check if we have registered the unqualified name into the list
6659 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6660 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6661 // the unqualified name is sufficient (and the fully qualified name might be
6662 // 'wrong' if there is difference in spelling in the template paramters (for example)
6663 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6664 // 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() );
6665 return;
6666 }
6667
6668 clang::QualType type(tdDef->getTypeForDecl(), 0);
6670 } else if (ns) {
6671 canon = ns->getCanonicalDecl();
6672 name = ND->getQualifiedNameAsString();
6673 } else {
6674 name = ND->getQualifiedNameAsString();
6675 }
6676
6677 // Supposedly we are being called while something is being
6678 // loaded ... let's now tell the autoloader to do the work
6679 // yet another time.
6680 SuspendAutoLoadingRAII autoLoadOff(this);
6681 // FIXME: There can be more than one TClass for a single decl.
6682 // for example vector<double> and vector<Double32_t>
6683 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6684 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6685 RefreshClassInfo(cl, canon, false);
6686 }
6687 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6688 // and update them too:
6689 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6690 // RefreshClassInfo(cl, tdDef, true);
6691}
6692
6693////////////////////////////////////////////////////////////////////////////////
6694/// No op: see TClingCallbacks
6695
6696void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6697{
6698}
6699
6700//______________________________________________________________________________
6701//FIXME: Factor out that function in TClass, because TClass does it already twice
6702void TCling::UpdateClassInfoWork(const char* item)
6703{
6704 // This is a no-op as part of the API.
6705 // TCling uses UpdateClassInfoWithDecl() instead.
6706}
6707
6708////////////////////////////////////////////////////////////////////////////////
6709/// Update all canvases at end the terminal input command.
6710
6712{
6713 TIter next(gROOT->GetListOfCanvases());
6714 TVirtualPad* canvas;
6715 while ((canvas = (TVirtualPad*)next())) {
6716 canvas->Update();
6717 }
6718}
6719
6720////////////////////////////////////////////////////////////////////////////////
6721
6722void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6723 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6724
6725 // If the transaction does not contain anything we can return earlier.
6726 if (!HandleNewTransaction(T)) return;
6727
6728 bool isTUTransaction = false;
6729 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6730 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6731 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6732 // The is the first transaction, we have to expose to meta
6733 // what's already in the AST.
6734 isTUTransaction = true;
6735 }
6736 }
6737
6738 std::set<const void*> TransactionDeclSet;
6739 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6740 const clang::Decl* WrapperFD = T.getWrapperFD();
6741 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6742 I != E; ++I) {
6743 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6744 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6745 continue;
6746
6747 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6748 DE = I->m_DGR.end(); DI != DE; ++DI) {
6749 if (*DI == WrapperFD)
6750 continue;
6751 TransactionDeclSet.insert(*DI);
6752 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6753 }
6754 }
6755 }
6756
6757 // The above might trigger more decls to be deserialized.
6758 // Thus the iteration over the deserialized decls must be last.
6759 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6760 E = T.deserialized_decls_end(); I != E; ++I) {
6761 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6762 DE = I->m_DGR.end(); DI != DE; ++DI)
6763 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6764 //FIXME: HandleNewDecl should take DeclGroupRef
6765 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6766 modifiedTClasses);
6767 }
6768 }
6769
6770
6771 // When fully building the reflection info in TClass, a deserialization
6772 // could be triggered, which may result in request for building the
6773 // reflection info for the same TClass. This in turn will clear the caches
6774 // for the TClass in-flight and cause null ptr derefs.
6775 // FIXME: This is a quick fix, solving most of the issues. The actual
6776 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6777 // itself until the update is done.
6778 //
6779 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6780 std::vector<TClass*>::iterator it;
6781 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6782 ((TCling*)gCling)->GetModTClasses().begin(),
6783 ((TCling*)gCling)->GetModTClasses().end(),
6784 modifiedTClassesDiff.begin());
6785 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6786
6787 // Lock the TClass for updates
6788 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6789 modifiedTClassesDiff.end());
6790 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6791 E = modifiedTClassesDiff.end(); I != E; ++I) {
6792 // Make sure the TClass has not been deleted.
6793 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6794 continue;
6795 }
6796 // Could trigger deserialization of decls.
6797 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6798 // Unlock the TClass for updates
6799 ((TCling*)gCling)->GetModTClasses().erase(*I);
6800
6801 }
6802}
6803
6804///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6805///
6806void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6807{
6809
6810 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6811 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6812 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6813 (TListOfEnums *)gROOT->GetListOfEnums());
6814
6815 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6816 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6817 I != E; ++I) {
6818 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6819 continue;
6820 if (I->m_Call == cling::Transaction::kCCINone) {
6821 UpdateListsOnUnloaded(*(*iNested));
6822 ++iNested;
6823 continue;
6824 }
6825
6826 for (auto &D : I->m_DGR)
6827 InvalidateCachedDecl(Lists, D);
6828 }
6829}
6830
6831///\brief Invalidate cached TCling information for the given global declaration.
6832///
6833void TCling::InvalidateGlobal(const Decl *D) {
6834 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6835 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6836 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6837 (TListOfEnums *)gROOT->GetListOfEnums());
6838 InvalidateCachedDecl(Lists, D);
6839}
6840
6841///\brief Invalidate cached TCling information for the given declaration, and
6842/// removed it from the appropriate object list.
6843///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6844/// TListOfFunctionTemplates&, TListOfEnums&>
6845/// of pointers to the (global/class) object lists.
6846///\param[in] D - Decl to discard.
6847///
6851 TListOfEnums*> &Lists, const Decl *D) {
6852 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6853 return;
6854
6855 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6856 TListOfFunctions &LOF = *(std::get<1>(Lists));
6857 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6858 TListOfEnums &LOE = *(std::get<3>(Lists));
6859
6860 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6861 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6862 if (LODM.GetClass())
6863 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6864 else
6865 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6866 } else if (isa<FunctionDecl>(D)) {
6868 } else if (isa<FunctionTemplateDecl>(D)) {
6870 } else if (isa<EnumDecl>(D)) {
6871 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6872 if (!E)
6873 return;
6874
6875 // Try to invalidate enumerators (for unscoped enumerations).
6876 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6878 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6879
6881 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6882 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6883 return;
6884
6885 std::vector<TClass *> Classes;
6886 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6887 return;
6888 for (auto &C : Classes) {
6889 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6890 (TListOfFunctions *)C->GetListOfMethods(),
6891 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6892 (TListOfEnums *)C->GetListOfEnums());
6893 for (auto &I : cast<DeclContext>(D)->decls())
6894 InvalidateCachedDecl(Lists, I);
6895
6896 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6897 if (D->getKind() != Decl::Namespace
6898 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6899 C->ResetClassInfo();
6900 }
6901 }
6902}
6903
6904////////////////////////////////////////////////////////////////////////////////
6905// If an autoparse was done during a transaction and that it is rolled back,
6906// we need to make sure the next request for the same autoparse will be
6907// honored.
6908void TCling::TransactionRollback(const cling::Transaction &T) {
6909 auto const &triter = fTransactionHeadersMap.find(&T);
6910 if (triter != fTransactionHeadersMap.end()) {
6911 std::size_t normNameHash = triter->second;
6912
6913 fLookedUpClasses.erase(normNameHash);
6914
6915 auto const &iter = fClassesHeadersMap.find(normNameHash);
6916 if (iter != fClassesHeadersMap.end()) {
6917 auto const &hNamesPtrs = iter->second;
6918 for (auto &hName : hNamesPtrs) {
6919 if (gDebug > 0) {
6920 Info("TransactionRollback",
6921 "Restoring ability to autoaparse: %s", hName);
6922 }
6923 fParsedPayloadsAddresses.erase(hName);
6924 }
6925 }
6926 }
6927}
6928
6929////////////////////////////////////////////////////////////////////////////////
6930
6931void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6932// R__LOCKGUARD_CLING(gInterpreterMutex);
6933// UpdateListOfLoadedSharedLibraries();
6934}
6935
6936////////////////////////////////////////////////////////////////////////////////
6937
6938void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6940 fSharedLibs = "";
6941}
6942
6943////////////////////////////////////////////////////////////////////////////////
6944/// Return the list of shared libraries loaded into the process.
6945
6947{
6950 return fSharedLibs;
6951}
6952
6953static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6954{
6955 if (!cls || !*cls)
6956 return {};
6957
6958 using namespace clang;
6959 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6960 /*type*/ nullptr, /*instantiate*/ false)) {
6961 if (!D->isFromASTFile()) {
6962 if (gDebug > 5)
6963 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6964 return {};
6965 }
6966 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6967 llvm::DenseSet<Module *> &m_TopLevelModules;
6968
6969 public:
6970 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6971 void Collect(const Decl *D) { Visit(D); }
6972
6973 void VisitDecl(const Decl *D)
6974 {
6975 // FIXME: Such case is described ROOT-7765 where
6976 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6977 // They are specified as #includes in the LinkDef file. This leads to
6978 // generation of incomplete modulemap files and this logic fails to
6979 // compute the corresponding module of D.
6980 // FIXME: If we want to support such a case, we should not rely on
6981 // the contents of the modulemap but mangle D and look it up in the
6982 // .so files.
6983 if (!D->hasOwningModule())
6984 return;
6985 if (Module *M = D->getOwningModule()->getTopLevelModule())
6986 m_TopLevelModules.insert(M);
6987 }
6988
6989 void VisitTemplateArgument(const TemplateArgument &TA)
6990 {
6991 switch (TA.getKind()) {
6992 case TemplateArgument::Null:
6993 case TemplateArgument::Integral:
6994 case TemplateArgument::Pack:
6995 case TemplateArgument::NullPtr:
6996 case TemplateArgument::Expression:
6997 case TemplateArgument::Template:
6998 case TemplateArgument::TemplateExpansion: return;
6999 case TemplateArgument::Type:
7000 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7001 return Visit(TagTy->getDecl());
7002 return;
7003 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7004 }
7005 llvm_unreachable("Invalid TemplateArgument::Kind!");
7006 }
7007
7008 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7009 {
7010 if (CTSD->getOwningModule())
7011 VisitDecl(CTSD);
7012 else
7013 VisitDecl(CTSD->getSpecializedTemplate());
7014 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7015 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7016 VisitTemplateArgument(*Arg);
7017 }
7018 }
7019 };
7020
7021 llvm::DenseSet<Module *> TopLevelModules;
7022 ModuleCollector m(TopLevelModules);
7023 m.Collect(D);
7024 std::string result;
7025 for (auto M : TopLevelModules) {
7026 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7027 // link declaration.
7028 if (!M->LinkLibraries.size())
7029 continue;
7030 // We have preloaded the Core module thus libCore.so
7031 if (M->Name == "Core")
7032 continue;
7033 assert(M->LinkLibraries.size() == 1);
7034 if (!result.empty())
7035 result += ' ';
7036 result += M->LinkLibraries[0].Library;
7037 }
7038 return result;
7039 }
7040 return {};
7041}
7042
7043////////////////////////////////////////////////////////////////////////////////
7044/// Get the list of shared libraries containing the code for class cls.
7045/// The first library in the list is the one containing the class, the
7046/// others are the libraries the first one depends on. Returns 0
7047/// in case the library is not found.
7048
7049const char* TCling::GetClassSharedLibs(const char* cls)
7050{
7051 if (fCxxModulesEnabled) {
7052 llvm::StringRef className = cls;
7053 // If we get a class name containing lambda, we cannot parse it and we
7054 // can exit early.
7055 // FIXME: This works around a bug when we are instantiating a template
7056 // make_unique and the substitution fails. Seen in most of the dataframe
7057 // tests.
7058 if (className.contains("(lambda)"))
7059 return nullptr;
7060 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7061 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7062 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7063 std::string libs = GetClassSharedLibsForModule(cls, LH);
7064 if (!libs.empty()) {
7065 fAutoLoadLibStorage.push_back(libs);
7066 return fAutoLoadLibStorage.back().c_str();
7067 }
7068 }
7069
7070 if (!cls || !*cls) {
7071 return 0;
7072 }
7073 // lookup class to find list of libraries
7074 if (fMapfile) {
7075 TEnvRec* libs_record = 0;
7076 libs_record = fMapfile->Lookup(cls);
7077 if (libs_record) {
7078 const char* libs = libs_record->GetValue();
7079 return (*libs) ? libs : 0;
7080 }
7081 else {
7082 // Try the old format...
7083 TString c = TString("Library.") + cls;
7084 // convert "::" to "@@", we used "@@" because TEnv
7085 // considers "::" a terminator
7086 c.ReplaceAll("::", "@@");
7087 // convert "-" to " ", since class names may have
7088 // blanks and TEnv considers a blank a terminator
7089 c.ReplaceAll(" ", "-");
7090 // Use TEnv::Lookup here as the rootmap file must start with Library.
7091 // and do not support using any stars (so we do not need to waste time
7092 // with the search made by TEnv::GetValue).
7093 TEnvRec* libs_record = 0;
7094 libs_record = fMapfile->Lookup(c);
7095 if (libs_record) {
7096 const char* libs = libs_record->GetValue();
7097 return (*libs) ? libs : 0;
7098 }
7099 }
7100 }
7101 return 0;
7102}
7103
7104/// This interface returns a list of dependent libraries in the form:
7105/// lib libA.so libB.so libC.so. The first library is the library we are
7106/// searching dependencies for.
7107/// Note: In order to speed up the search, we display the dependencies of the
7108/// libraries which are not yet loaded. For instance, if libB.so was already
7109/// loaded the list would contain: lib libA.so libC.so.
7110static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7111 cling::Interpreter *interp,
7112 bool skipLoadedLibs = true)
7113{
7114 TString LibFullPath(lib);
7115 if (!llvm::sys::path::is_absolute(lib)) {
7116 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7117 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7118 return "";
7119 }
7120 } else {
7121 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7122 lib = llvm::sys::path::filename(lib).str();
7123 }
7124
7125 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7126 if (!ObjF) {
7127 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7128 return "";
7129 }
7130
7131 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7132
7133 std::set<string> DedupSet;
7134 std::string Result = lib + ' ';
7135 for (const auto &S : BinObjFile->symbols()) {
7136 uint32_t Flags = llvm::cantFail(S.getFlags());
7137 // Skip defined symbols: we have them.
7138 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7139 continue;
7140 // Skip undefined weak symbols: if we don't have them we won't need them.
7141 // `__gmon_start__` being a typical example.
7142 if (Flags & llvm::object::SymbolRef::SF_Weak)
7143 continue;
7144 llvm::Expected<StringRef> SymNameErr = S.getName();
7145 if (!SymNameErr) {
7146 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7147 continue;
7148 }
7149 llvm::StringRef SymName = SymNameErr.get();
7150 if (SymName.empty())
7151 continue;
7152
7153 if (BinObjFile->isELF()) {
7154 // Skip the symbols which are part of the C/C++ runtime and have a
7155 // fixed library version. See binutils ld VERSION. Those reside in
7156 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7157 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7158 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7159 continue;
7160
7161 // Those are 'weak undefined' symbols produced by gcc. We can
7162 // ignore them.
7163 // FIXME: It is unclear whether we can ignore all weak undefined
7164 // symbols:
7165 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7166 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7167 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7168 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7169 if (SymName == RegisterClasses ||
7170 SymName == RegisterCloneTable ||
7171 SymName == DeregisterCloneTable)
7172 continue;
7173 }
7174
7175 // If we can find the address of the symbol, we have loaded it. Skip.
7176 if (skipLoadedLibs) {
7177 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7178 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7179 continue;
7180 }
7181
7183 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7184 // The expected output is just filename without the full path, which
7185 // is not very accurate, because our Dyld implementation might find
7186 // a match in location a/b/c.so and if we return just c.so ROOT might
7187 // resolve it to y/z/c.so and there we might not be ABI compatible.
7188 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7189 if (!found.empty()) {
7190 std::string cand = llvm::sys::path::filename(found).str();
7191 if (!DedupSet.insert(cand).second)
7192 continue;
7193
7194 Result += cand + ' ';
7195 }
7196 }
7197
7198 return Result;
7199}
7200
7201static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7202{
7203 // Check if we have parsed a rootmap file.
7204 llvm::SmallString<256> rootmapName;
7205 if (!lib.startswith("lib"))
7206 rootmapName.append("lib");
7207
7208 rootmapName.append(llvm::sys::path::filename(lib));
7209 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7210
7211 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7212 return true;
7213
7214 // Perform a last resort by dropping the lib prefix.
7215 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7216 if (rootmapNameNoLib.consume_front("lib"))
7217 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7218
7219 return false;
7220}
7221
7222static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7223{
7224 if (gCling->HasPCMForLibrary(lib.data()))
7225 return true;
7226
7227 return hasParsedRootmapForLibrary(lib);
7228}
7229
7230////////////////////////////////////////////////////////////////////////////////
7231/// Get the list a libraries on which the specified lib depends. The
7232/// returned string contains as first element the lib itself.
7233/// Returns 0 in case the lib does not exist or does not have
7234/// any dependencies. If useDyld is true, we iterate through all available
7235/// libraries and try to construct the dependency chain by resolving each
7236/// symbol.
7237
7238const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7239{
7240 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7241 return nullptr;
7242
7243 if (!hasParsedRootmapForLibrary(lib)) {
7244 llvm::SmallString<512> rootmapName(lib);
7245 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7246 if (llvm::sys::fs::exists(rootmapName)) {
7247 if (gDebug > 0)
7248 Info("Load", "loading %s", rootmapName.c_str());
7249 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7250 }
7251 }
7252
7253 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7254 if (gDebug > 0)
7255 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7256 }
7257
7258 if (useDyld) {
7259 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7260 if (!libs.empty()) {
7261 fAutoLoadLibStorage.push_back(libs);
7262 return fAutoLoadLibStorage.back().c_str();
7263 }
7264 }
7265
7266 if (!fMapfile || !lib || !lib[0]) {
7267 return 0;
7268 }
7269 TString libname(lib);
7270 Ssiz_t idx = libname.Last('.');
7271 if (idx != kNPOS) {
7272 libname.Remove(idx);
7273 }
7274 TEnvRec* rec;
7275 TIter next(fMapfile->GetTable());
7276 size_t len = libname.Length();
7277 while ((rec = (TEnvRec*) next())) {
7278 const char* libs = rec->GetValue();
7279 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7280 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7281 return libs;
7282 }
7283 }
7284 return 0;
7285}
7286
7287////////////////////////////////////////////////////////////////////////////////
7288/// If error messages are disabled, the interpreter should suppress its
7289/// failures and warning messages from stdout.
7290
7292{
7293#if defined(R__MUST_REVISIT)
7294#if R__MUST_REVISIT(6,2)
7295 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7296#endif
7297#endif
7298 return kTRUE;
7299}
7300
7301////////////////////////////////////////////////////////////////////////////////
7302/// If error messages are disabled, the interpreter should suppress its
7303/// failures and warning messages from stdout. Return the previous state.
7304
7306{
7307#if defined(R__MUST_REVISIT)
7308#if R__MUST_REVISIT(6,2)
7309 Warning("SetErrorMessages", "Interface not available yet.");
7310#endif
7311#endif
7313}
7314
7315////////////////////////////////////////////////////////////////////////////////
7316/// Refresh the list of include paths known to the interpreter and return it
7317/// with -I prepended.
7318
7320{
7322
7323 fIncludePath = "";
7324
7325 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7326 //false - no system header, true - with flags.
7327 fInterpreter->GetIncludePaths(includePaths, false, true);
7328 if (const size_t nPaths = includePaths.size()) {
7329 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7330
7331 for (size_t i = 0; i < nPaths; i += 2) {
7332 if (i)
7333 fIncludePath.Append(' ');
7334 fIncludePath.Append(includePaths[i].c_str());
7335
7336 if (includePaths[i] != "-I")
7337 fIncludePath.Append(' ');
7338 fIncludePath.Append('"');
7339 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7340 fIncludePath.Append('"');
7341 }
7342 }
7343
7344 return fIncludePath;
7345}
7346
7347////////////////////////////////////////////////////////////////////////////////
7348/// Return the directory containing CINT's stl cintdlls.
7349
7350const char* TCling::GetSTLIncludePath() const
7351{
7352 return "";
7353}
7354
7355//______________________________________________________________________________
7356// M I S C
7357//______________________________________________________________________________
7358
7359int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7360{
7361 // Interface to cling function
7362 return 0;
7363}
7364
7365////////////////////////////////////////////////////////////////////////////////
7366/// Interface to cling function
7367
7368int TCling::DisplayIncludePath(FILE *fout) const
7369{
7370 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
7371
7372 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7373 //false - no system header, true - with flags.
7374 fInterpreter->GetIncludePaths(includePaths, false, true);
7375 if (const size_t nPaths = includePaths.size()) {
7376 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7377
7378 std::string allIncludes("include path:");
7379 for (size_t i = 0; i < nPaths; i += 2) {
7380 allIncludes += ' ';
7381 allIncludes += includePaths[i];
7382
7383 if (includePaths[i] != "-I")
7384 allIncludes += ' ';
7385 allIncludes += includePaths[i + 1];
7386 }
7387
7388 fprintf(fout, "%s\n", allIncludes.c_str());
7389 }
7390
7391 return 0;
7392}
7393
7394////////////////////////////////////////////////////////////////////////////////
7395/// Interface to cling function
7396
7397void* TCling::FindSym(const char* entry) const
7398{
7399 return fInterpreter->getAddressOfGlobal(entry);
7400}
7401
7402////////////////////////////////////////////////////////////////////////////////
7403/// Let the interpreter issue a generic error, and set its error state.
7404
7405void TCling::GenericError(const char* error) const
7406{
7407#if defined(R__MUST_REVISIT)
7408#if R__MUST_REVISIT(6,2)
7409 Warning("GenericError","Interface not available yet.");
7410#endif
7411#endif
7412}
7413
7414////////////////////////////////////////////////////////////////////////////////
7415/// This routines used to return the address of the internal wrapper
7416/// function (of the interpreter) that was used to call *all* the
7417/// interpreted functions that were bytecode compiled (no longer
7418/// interpreted line by line). In Cling, there is no such
7419/// wrapper function.
7420/// In practice this routines was use to decipher whether the
7421/// pointer returns by InterfaceMethod could be used to uniquely
7422/// represent the function. In Cling if the function is in a
7423/// useable state (its compiled version is available), this is
7424/// always the case.
7425/// See TClass::GetMethod.
7426
7428{
7429 return 0;
7430}
7431
7432////////////////////////////////////////////////////////////////////////////////
7433/// Interface to cling function
7434
7436{
7437#if defined(R__MUST_REVISIT)
7438#if R__MUST_REVISIT(6,2)
7439 Warning("GetSecurityError", "Interface not available yet.");
7440#endif
7441#endif
7442 return 0;
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446/// Load a source file or library called path into the interpreter.
7447
7448int TCling::LoadFile(const char* path) const
7449{
7450 cling::Interpreter::CompilationResult compRes;
7451 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7452 return compRes == cling::Interpreter::kFailure;
7453}
7454
7455////////////////////////////////////////////////////////////////////////////////
7456/// Load the declarations from text into the interpreter.
7457/// Note that this cannot be (top level) statements; text must contain
7458/// top level declarations.
7459/// Returns true on success, false on failure.
7460
7461Bool_t TCling::LoadText(const char* text) const
7462{
7463 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7464}
7465
7466////////////////////////////////////////////////////////////////////////////////
7467/// Interface to cling function
7468
7469const char* TCling::MapCppName(const char* name) const
7470{
7471 TTHREAD_TLS_DECL(std::string,buffer);
7473 return buffer.c_str(); // NOLINT
7474}
7475
7476////////////////////////////////////////////////////////////////////////////////
7477/// [Place holder for Mutex Lock]
7478/// Provide the interpreter with a way to
7479/// acquire a lock used to protect critical section
7480/// of its code (non-thread safe parts).
7481
7482void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7483{
7484 // nothing to do for now.
7485}
7486
7487////////////////////////////////////////////////////////////////////////////////
7488/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7489/// release a lock used to protect critical section
7490/// of its code (non-thread safe parts).
7491
7492void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7493{
7494 // nothing to do for now.
7495}
7496
7497////////////////////////////////////////////////////////////////////////////////
7498/// Returns if class AutoLoading is currently enabled.
7499
7501{
7502 if (IsFromRootCling())
7503 return false;
7504 if (!fClingCallbacks)
7505 return false;
7507}
7508
7509////////////////////////////////////////////////////////////////////////////////
7510/// Enable/Disable the AutoLoading of libraries.
7511/// Returns the old value, i.e whether it was enabled or not.
7512
7513int TCling::SetClassAutoLoading(int autoload) const
7514{
7515 // If no state change is required, exit early.
7516 // FIXME: In future we probably want to complain if we made a request which
7517 // was with the same state as before in order to catch programming errors.
7518 if ((bool) autoload == IsClassAutoLoadingEnabled())
7519 return autoload;
7520
7521 assert(fClingCallbacks && "We must have callbacks!");
7522 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7524 return oldVal;
7525}
7526
7527////////////////////////////////////////////////////////////////////////////////
7528/// Enable/Disable the Autoparsing of headers.
7529/// Returns the old value, i.e whether it was enabled or not.
7530
7532{
7533 bool oldVal = fHeaderParsingOnDemand;
7534 fHeaderParsingOnDemand = autoparse;
7535 return oldVal;
7536}
7537
7538////////////////////////////////////////////////////////////////////////////////
7539/// Suspend the Autoparsing of headers.
7540/// Returns the old value, i.e whether it was suspended or not.
7541
7546 return old;
7547}
7548
7549////////////////////////////////////////////////////////////////////////////////
7550/// Set a callback to receive error messages.
7551
7553{
7554#if defined(R__MUST_REVISIT)
7555#if R__MUST_REVISIT(6,2)
7556 Warning("SetErrmsgcallback", "Interface not available yet.");
7557#endif
7558#endif
7559}
7560
7562{
7563 if (enable) {
7564 auto consumer = new TClingDelegateDiagnosticPrinter(
7565 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7566 fInterpreter->getCI()->getLangOpts(),
7567 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7568 if (Level == clang::DiagnosticsEngine::Warning) {
7569 ::Warning("cling", "%s", Info.c_str());
7570 } else if (Level == clang::DiagnosticsEngine::Error
7571 || Level == clang::DiagnosticsEngine::Fatal) {
7572 ::Error("cling", "%s", Info.c_str());
7573 } else {
7574 ::Info("cling", "%s", Info.c_str());
7575 }
7576 });
7577 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7578 } else {
7579 fInterpreter->replaceDiagnosticConsumer(nullptr);
7580 }
7581}
7582
7583
7584////////////////////////////////////////////////////////////////////////////////
7585/// Create / close a scope for temporaries. No-op for cling; use
7586/// cling::Value instead.
7587
7588void TCling::SetTempLevel(int val) const
7589{
7590}
7591
7592////////////////////////////////////////////////////////////////////////////////
7593
7594int TCling::UnloadFile(const char* path) const
7595{
7596 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7597 std::string canonical = DLM->lookupLibrary(path);
7598 if (canonical.empty()) {
7599 canonical = path;
7600 }
7601 // Unload a shared library or a source file.
7602 cling::Interpreter::CompilationResult compRes;
7603 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7604 return compRes == cling::Interpreter::kFailure;
7605}
7606
7607std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7608 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7609}
7610
7611////////////////////////////////////////////////////////////////////////////////
7612/// The call to Cling's tab complition.
7613
7614void TCling::CodeComplete(const std::string& line, size_t& cursor,
7615 std::vector<std::string>& completions)
7616{
7617 fInterpreter->codeComplete(line, cursor, completions);
7618}
7619
7620////////////////////////////////////////////////////////////////////////////////
7621/// Get the interpreter value corresponding to the statement.
7623{
7624 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7625 auto compRes = fInterpreter->evaluate(code, *V);
7626 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7627}
7628
7629////////////////////////////////////////////////////////////////////////////////
7630
7632{
7633 using namespace cling;
7634 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7636}
7637
7638////////////////////////////////////////////////////////////////////////////////
7639/// Register value as a temporary, extending its lifetime to that of the
7640/// interpreter. This is needed for TCling's compatibility interfaces
7641/// returning long - the address of the temporary objects.
7642/// As such, "simple" types don't need to be stored; they are returned by
7643/// value; only pointers / references / objects need to be stored.
7644
7645void TCling::RegisterTemporary(const cling::Value& value)
7646{
7647 if (value.isValid() && value.needsManagedAllocation()) {
7649 fTemporaries->push_back(value);
7650 }
7651}
7652
7653////////////////////////////////////////////////////////////////////////////////
7654/// If the interpreter encounters Name, check whether that is an object ROOT
7655/// could retrieve. To not re-read objects from disk, cache the name/object
7656/// pair for a given LookupCtx.
7657
7658TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7659{
7660 // The call to FindSpecialObject might induces any kind of use
7661 // of the interpreter ... (library loading, function calling, etc.)
7662 // ... and we _know_ we are in the middle of parsing, so let's make
7663 // sure to save the state and then restore it.
7664
7665 if (gDirectory) {
7666 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7667 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7668 auto iSpecObj = iSpecObjMap->second.find(Name);
7669 if (iSpecObj != iSpecObjMap->second.end()) {
7670 LookupCtx = gDirectory;
7671 return iSpecObj->second;
7672 }
7673 }
7674 }
7675
7676 // Save state of the PP
7677 Sema &SemaR = fInterpreter->getSema();
7678 ASTContext& C = SemaR.getASTContext();
7679 Preprocessor &PP = SemaR.getPreprocessor();
7680 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7681 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7682 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7683 // After we have saved the token reset the current one to something which
7684 // is safe (semi colon usually means empty decl)
7685 Token& Tok = const_cast<Token&>(P.getCurToken());
7686 Tok.setKind(tok::semi);
7687
7688 // We can't PushDeclContext, because we go up and the routine that pops
7689 // the DeclContext assumes that we drill down always.
7690 // We have to be on the global context. At that point we are in a
7691 // wrapper function so the parent context must be the global.
7692 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7693 SemaR.TUScope);
7694
7695 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7696 if (specObj) {
7697 if (!LookupCtx) {
7698 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7699 } else {
7700 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7701 }
7702 }
7703 return specObj;
7704}
7705
7706////////////////////////////////////////////////////////////////////////////////
7707/// Inject function as a friend into klass.
7708/// With function being f in void f() {new N::PrivKlass(); } this enables
7709/// I/O of non-public classes.
7710
7711void TCling::AddFriendToClass(clang::FunctionDecl* function,
7712 clang::CXXRecordDecl* klass) const
7713{
7714 using namespace clang;
7715 ASTContext& Ctx = klass->getASTContext();
7716 FriendDecl::FriendUnion friendUnion(function);
7717 // one dummy object for the source location
7718 SourceLocation sl;
7719 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7720 klass->pushFriendDecl(friendDecl);
7721}
7722
7723//______________________________________________________________________________
7724//
7725// DeclId getter.
7726//
7727
7728////////////////////////////////////////////////////////////////////////////////
7729/// Return a unique identifier of the declaration represented by the
7730/// CallFunc
7731
7733{
7734 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7735 return 0;
7736}
7737
7738////////////////////////////////////////////////////////////////////////////////
7739/// Return a (almost) unique identifier of the declaration represented by the
7740/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7741/// when the underlying class is a template instance involving one of the
7742/// opaque typedef.
7743
7745{
7746 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7747 return 0;
7748}
7749
7750////////////////////////////////////////////////////////////////////////////////
7751/// Return a unique identifier of the declaration represented by the
7752/// MethodInfo
7753
7755{
7756 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7757 return 0;
7758}
7759
7760////////////////////////////////////////////////////////////////////////////////
7761/// Return a unique identifier of the declaration represented by the
7762/// MethodInfo
7763
7765{
7766 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7767 return 0;
7768}
7769
7770////////////////////////////////////////////////////////////////////////////////
7771/// Return a unique identifier of the declaration represented by the
7772/// TypedefInfo
7773
7775{
7776 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7777 return 0;
7778}
7779
7780//______________________________________________________________________________
7781//
7782// CallFunc interface
7783//
7784
7785////////////////////////////////////////////////////////////////////////////////
7786
7787void TCling::CallFunc_Delete(CallFunc_t* func) const
7788{
7789 delete (TClingCallFunc*) func;
7790}
7791
7792////////////////////////////////////////////////////////////////////////////////
7793
7794void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7795{
7796 TClingCallFunc* f = (TClingCallFunc*) func;
7797 f->Exec(address);
7798}
7799
7800////////////////////////////////////////////////////////////////////////////////
7801
7802void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7803{
7804 TClingCallFunc* f = (TClingCallFunc*) func;
7805 f->Exec(address, &val);
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809
7810void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7811{
7812 TClingCallFunc* f = (TClingCallFunc*) func;
7813 f->ExecWithReturn(address, ret);
7814}
7815
7816////////////////////////////////////////////////////////////////////////////////
7817
7818void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7819 const void* args[] /*=0*/,
7820 int nargs /*=0*/,
7821 void* ret/*=0*/) const
7822{
7823 TClingCallFunc* f = (TClingCallFunc*) func;
7824 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7825}
7826
7827////////////////////////////////////////////////////////////////////////////////
7828
7829Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7830{
7831 TClingCallFunc* f = (TClingCallFunc*) func;
7832 return f->ExecInt(address);
7833}
7834
7835////////////////////////////////////////////////////////////////////////////////
7836
7837Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7838{
7839 TClingCallFunc* f = (TClingCallFunc*) func;
7840 return f->ExecInt64(address);
7841}
7842
7843////////////////////////////////////////////////////////////////////////////////
7844
7845Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7846{
7847 TClingCallFunc* f = (TClingCallFunc*) func;
7848 return f->ExecDouble(address);
7849}
7850
7851////////////////////////////////////////////////////////////////////////////////
7852
7853CallFunc_t* TCling::CallFunc_Factory() const
7854{
7856 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860
7861CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7862{
7863 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7864}
7865
7866////////////////////////////////////////////////////////////////////////////////
7867
7868MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7869{
7870 TClingCallFunc* f = (TClingCallFunc*) func;
7871 return (MethodInfo_t*) f->FactoryMethod();
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7877{
7878 TClingCallFunc* f = (TClingCallFunc*) func;
7879 f->IgnoreExtraArgs(ignore);
7880}
7881
7882////////////////////////////////////////////////////////////////////////////////
7883
7884void TCling::CallFunc_Init(CallFunc_t* func) const
7885{
7887 TClingCallFunc* f = (TClingCallFunc*) func;
7888 f->Init();
7889}
7890
7891////////////////////////////////////////////////////////////////////////////////
7892
7893bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7894{
7895 TClingCallFunc* f = (TClingCallFunc*) func;
7896 return f->IsValid();
7897}
7898
7899////////////////////////////////////////////////////////////////////////////////
7900
7902TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7903{
7904 TClingCallFunc* f = (TClingCallFunc*) func;
7905 return f->IFacePtr();
7906}
7907
7908////////////////////////////////////////////////////////////////////////////////
7909
7910void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7911{
7912 TClingCallFunc* f = (TClingCallFunc*) func;
7913 f->ResetArg();
7914}
7915
7916////////////////////////////////////////////////////////////////////////////////
7917
7918void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7919{
7920 TClingCallFunc* f = (TClingCallFunc*) func;
7921 f->SetArg(param);
7922}
7923
7924////////////////////////////////////////////////////////////////////////////////
7925
7926void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7927{
7928 TClingCallFunc* f = (TClingCallFunc*) func;
7929 f->SetArg(param);
7930}
7931
7932////////////////////////////////////////////////////////////////////////////////
7933
7934void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7935{
7936 TClingCallFunc* f = (TClingCallFunc*) func;
7937 f->SetArg(param);
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941
7942void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7943{
7944 TClingCallFunc* f = (TClingCallFunc*) func;
7945 f->SetArg(param);
7946}
7947
7948////////////////////////////////////////////////////////////////////////////////
7949
7950void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7951{
7952 TClingCallFunc* f = (TClingCallFunc*) func;
7953 f->SetArg(param);
7954}
7955
7956////////////////////////////////////////////////////////////////////////////////
7957
7958void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7959{
7960 TClingCallFunc* f = (TClingCallFunc*) func;
7961 f->SetArg(param);
7962}
7963
7964////////////////////////////////////////////////////////////////////////////////
7965
7966void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
7967{
7968 TClingCallFunc* f = (TClingCallFunc*) func;
7969 f->SetArgArray(paramArr, nparam);
7970}
7971
7972////////////////////////////////////////////////////////////////////////////////
7973
7974void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7975{
7976 TClingCallFunc* f = (TClingCallFunc*) func;
7977 f->SetArgs(param);
7978}
7979
7980////////////////////////////////////////////////////////////////////////////////
7981
7982void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
7983{
7984 TClingCallFunc* f = (TClingCallFunc*) func;
7985 TClingClassInfo* ci = (TClingClassInfo*) info;
7986 f->SetFunc(ci, method, params, offset);
7987}
7988
7989////////////////////////////////////////////////////////////////////////////////
7990
7991void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
7992{
7993 TClingCallFunc* f = (TClingCallFunc*) func;
7994 TClingClassInfo* ci = (TClingClassInfo*) info;
7995 f->SetFunc(ci, method, params, objectIsConst, offset);
7996}
7997////////////////////////////////////////////////////////////////////////////////
7998
7999void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8000{
8001 TClingCallFunc* f = (TClingCallFunc*) func;
8002 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8003 f->SetFunc(minfo);
8004}
8005
8006////////////////////////////////////////////////////////////////////////////////
8007/// Interface to cling function
8008
8009void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8010{
8011 TClingCallFunc* f = (TClingCallFunc*) func;
8012 TClingClassInfo* ci = (TClingClassInfo*) info;
8013 f->SetFuncProto(ci, method, proto, offset, mode);
8014}
8015
8016////////////////////////////////////////////////////////////////////////////////
8017/// Interface to cling function
8018
8019void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8020{
8021 TClingCallFunc* f = (TClingCallFunc*) func;
8022 TClingClassInfo* ci = (TClingClassInfo*) info;
8023 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8024}
8025
8026////////////////////////////////////////////////////////////////////////////////
8027/// Interface to cling function
8028
8029void 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
8030{
8031 TClingCallFunc* f = (TClingCallFunc*) func;
8032 TClingClassInfo* ci = (TClingClassInfo*) info;
8033 llvm::SmallVector<clang::QualType, 4> funcProto;
8034 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8035 iter != end; ++iter) {
8036 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8037 }
8038 f->SetFuncProto(ci, method, funcProto, offset, mode);
8039}
8040
8041////////////////////////////////////////////////////////////////////////////////
8042/// Interface to cling function
8043
8044void 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
8045{
8046 TClingCallFunc* f = (TClingCallFunc*) func;
8047 TClingClassInfo* ci = (TClingClassInfo*) info;
8048 llvm::SmallVector<clang::QualType, 4> funcProto;
8049 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8050 iter != end; ++iter) {
8051 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8052 }
8053 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8054}
8055
8056std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8057{
8058 TClingCallFunc *f = (TClingCallFunc *)func;
8059 std::string wrapper_name;
8060 std::string wrapper;
8061 f->get_wrapper_code(wrapper_name, wrapper);
8062 return wrapper;
8063}
8064
8065//______________________________________________________________________________
8066//
8067// ClassInfo interface
8068//
8069
8070////////////////////////////////////////////////////////////////////////////////
8071/// Return true if the entity pointed to by 'declid' is declared in
8072/// the context described by 'info'. If info is null, look into the
8073/// global scope (translation unit scope).
8074
8075Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8076{
8077 if (!declid)
8078 return kFALSE;
8079
8080 const clang::DeclContext *ctxt = nullptr;
8081 if (info) {
8082 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8083 } else {
8084 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8085 }
8086 if (!ctxt)
8087 return kFALSE;
8088
8089 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8090 if (!decl)
8091 return kFALSE;
8092
8093 const clang::DeclContext *declDC = decl->getDeclContext();
8094 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8095 while (true) {
8096 if (declDC->isTransparentContext()) {
8097 declDC = declDC->getParent();
8098 continue;
8099 }
8100 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8101 if (declRD->isAnonymousStructOrUnion()) {
8102 declDC = declRD->getParent();
8103 continue;
8104 }
8105 }
8106 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8107 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8108 declDC = declNS->getParent();
8109 continue;
8110 }
8111 }
8112 break;
8113 }
8114
8115 return declDC->Equals(ctxt);
8116}
8117
8118////////////////////////////////////////////////////////////////////////////////
8119
8121{
8122 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8123 return TClinginfo->ClassProperty();
8124}
8125
8126////////////////////////////////////////////////////////////////////////////////
8127
8128void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8129{
8130 delete (TClingClassInfo*) cinfo;
8131}
8132
8133////////////////////////////////////////////////////////////////////////////////
8134
8135void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8136{
8137 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8138 TClinginfo->Delete(arena,*fNormalizedCtxt);
8139}
8140
8141////////////////////////////////////////////////////////////////////////////////
8142
8143void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8144{
8145 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8146 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8147}
8148
8149////////////////////////////////////////////////////////////////////////////////
8150
8151void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8152{
8153 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8154 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8155}
8156
8157////////////////////////////////////////////////////////////////////////////////
8158
8159ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8160{
8162 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8163}
8164
8165////////////////////////////////////////////////////////////////////////////////
8166
8167ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8168{
8169 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8170}
8171
8172////////////////////////////////////////////////////////////////////////////////
8173
8174ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8175{
8177 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8178}
8179
8180ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8181{
8183 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8184}
8185
8186
8187////////////////////////////////////////////////////////////////////////////////
8188
8189int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8190{
8191 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8192 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8193}
8194
8195////////////////////////////////////////////////////////////////////////////////
8196
8197bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8198{
8199 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8201}
8202
8203////////////////////////////////////////////////////////////////////////////////
8204
8205bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8206{
8207 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8208 return TClinginfo->HasMethod(name);
8209}
8210
8211////////////////////////////////////////////////////////////////////////////////
8212
8213void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8214{
8216 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8217 TClinginfo->Init(name);
8218}
8219
8220////////////////////////////////////////////////////////////////////////////////
8221
8222void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8223{
8225 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8226 TClinginfo->Init(tagnum);
8227}
8228
8229////////////////////////////////////////////////////////////////////////////////
8230
8231bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8232{
8233 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8234 return TClinginfo->IsBase(name);
8235}
8236
8237////////////////////////////////////////////////////////////////////////////////
8238
8239bool TCling::ClassInfo_IsEnum(const char* name) const
8240{
8242}
8243
8244////////////////////////////////////////////////////////////////////////////////
8245
8247{
8248 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8249 return TClinginfo->IsScopedEnum();
8250}
8251
8252
8253////////////////////////////////////////////////////////////////////////////////
8254
8256{
8257 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8258 return TClinginfo->GetUnderlyingType();
8259}
8260
8261
8262////////////////////////////////////////////////////////////////////////////////
8263
8264bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8265{
8266 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8267 return TClinginfo->IsLoaded();
8268}
8269
8270////////////////////////////////////////////////////////////////////////////////
8271
8272bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8273{
8274 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8275 return TClinginfo->IsValid();
8276}
8277
8278////////////////////////////////////////////////////////////////////////////////
8279
8280bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8281{
8282 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8283 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8284}
8285
8286////////////////////////////////////////////////////////////////////////////////
8287
8288bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8289{
8290 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8291 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8292}
8293
8294////////////////////////////////////////////////////////////////////////////////
8295
8296int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8297{
8298 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8299 return TClinginfo->Next();
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303
8304void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8305{
8306 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8307 return TClinginfo->New(*fNormalizedCtxt);
8308}
8309
8310////////////////////////////////////////////////////////////////////////////////
8311
8312void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8313{
8314 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8315 return TClinginfo->New(n,*fNormalizedCtxt);
8316}
8317
8318////////////////////////////////////////////////////////////////////////////////
8319
8320void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8321{
8322 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8323 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8328void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8329{
8330 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8331 return TClinginfo->New(arena,*fNormalizedCtxt);
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8336Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8337{
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8339 return TClinginfo->Property();
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8345{
8346 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8347 return TClinginfo->Size();
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8352Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8353{
8354 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8355 return TClinginfo->Tagnum();
8356}
8357
8358////////////////////////////////////////////////////////////////////////////////
8359
8360const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8361{
8362 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8363 return TClinginfo->FileName();
8364}
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8368const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8369{
8370 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8371 TTHREAD_TLS_DECL(std::string,output);
8372 TClinginfo->FullName(output,*fNormalizedCtxt);
8373 return output.c_str(); // NOLINT
8374}
8375
8376////////////////////////////////////////////////////////////////////////////////
8377
8378const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8379{
8380 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8381 return TClinginfo->Name();
8382}
8383
8384////////////////////////////////////////////////////////////////////////////////
8385
8386const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8387{
8388 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8389 return TClinginfo->Title();
8390}
8391
8392////////////////////////////////////////////////////////////////////////////////
8393
8394const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8395{
8396 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8397 return TClinginfo->TmpltName();
8398}
8399
8400
8401
8402//______________________________________________________________________________
8403//
8404// BaseClassInfo interface
8405//
8406
8407////////////////////////////////////////////////////////////////////////////////
8408
8409void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8410{
8411 delete(TClingBaseClassInfo*) bcinfo;
8412}
8413
8414////////////////////////////////////////////////////////////////////////////////
8415
8416BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8417{
8419 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8420 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8421}
8422
8423////////////////////////////////////////////////////////////////////////////////
8424
8425BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8426 ClassInfo_t* base) const
8427{
8429 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8430 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8431 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8432}
8433
8434////////////////////////////////////////////////////////////////////////////////
8435
8436int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8437{
8438 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8439 return TClinginfo->Next();
8440}
8441
8442////////////////////////////////////////////////////////////////////////////////
8443
8444int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8445{
8446 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8447 return TClinginfo->Next(onlyDirect);
8448}
8449
8450////////////////////////////////////////////////////////////////////////////////
8451
8452Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8453{
8454 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8455 return TClinginfo->Offset(address, isDerivedObject);
8456}
8457
8458////////////////////////////////////////////////////////////////////////////////
8459
8460Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8461{
8462 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8463 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8464 // Offset to the class itself.
8465 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8466 return 0;
8467 }
8468 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8469}
8470
8471////////////////////////////////////////////////////////////////////////////////
8472
8473Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8474{
8475 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8476 return TClinginfo->Property();
8477}
8478
8479////////////////////////////////////////////////////////////////////////////////
8480
8481ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8482{
8483 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8484 return (ClassInfo_t *)TClinginfo->GetBase();
8485}
8486
8487////////////////////////////////////////////////////////////////////////////////
8488
8489Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8490{
8491 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8492 return TClinginfo->Tagnum();
8493}
8494
8495////////////////////////////////////////////////////////////////////////////////
8496
8497const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8498{
8499 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8500 TTHREAD_TLS_DECL(std::string,output);
8501 TClinginfo->FullName(output,*fNormalizedCtxt);
8502 return output.c_str(); // NOLINT
8503}
8504
8505////////////////////////////////////////////////////////////////////////////////
8506
8507const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8508{
8509 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8510 return TClinginfo->Name();
8511}
8512
8513////////////////////////////////////////////////////////////////////////////////
8514
8515const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8516{
8517 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8518 return TClinginfo->TmpltName();
8519}
8520
8521//______________________________________________________________________________
8522//
8523// DataMemberInfo interface
8524//
8525
8526////////////////////////////////////////////////////////////////////////////////
8527
8528int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8529{
8530 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8531 return TClinginfo->ArrayDim();
8532}
8533
8534////////////////////////////////////////////////////////////////////////////////
8535
8536void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8537{
8538 delete(TClingDataMemberInfo*) dminfo;
8539}
8540
8541////////////////////////////////////////////////////////////////////////////////
8542
8543DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8544{
8546 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8547 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551
8552DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8553{
8555 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8556 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8557 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8558}
8559
8560////////////////////////////////////////////////////////////////////////////////
8561
8562DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8563{
8564 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8565 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8566}
8567
8568////////////////////////////////////////////////////////////////////////////////
8569
8570bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8571{
8572 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8573 return TClinginfo->IsValid();
8574}
8575
8576////////////////////////////////////////////////////////////////////////////////
8577
8578int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8579{
8580 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8581 return TClinginfo->MaxIndex(dim);
8582}
8583
8584////////////////////////////////////////////////////////////////////////////////
8585
8586int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8587{
8588 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8589 return TClinginfo->Next();
8590}
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8594Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8595{
8596 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8597 return TClinginfo->Offset();
8598}
8599
8600////////////////////////////////////////////////////////////////////////////////
8601
8602Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8603{
8604 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8605 return TClinginfo->Property();
8606}
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8610Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8611{
8612 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8613 return TClinginfo->TypeProperty();
8614}
8615
8616////////////////////////////////////////////////////////////////////////////////
8617
8618int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8619{
8620 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8621 return TClinginfo->TypeSize();
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625
8626const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8627{
8628 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8629 return TClinginfo->TypeName();
8630}
8631
8632////////////////////////////////////////////////////////////////////////////////
8633
8634const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8635{
8636 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8637 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8638}
8639
8640////////////////////////////////////////////////////////////////////////////////
8641
8642const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8643{
8644 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8645 return TClinginfo->Name();
8646}
8647
8648////////////////////////////////////////////////////////////////////////////////
8649
8650const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8651{
8652 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8653 return TClinginfo->Title();
8654}
8655
8656////////////////////////////////////////////////////////////////////////////////
8657
8658const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8659{
8660 TTHREAD_TLS_DECL(std::string,result);
8661
8662 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8663 result = TClinginfo->ValidArrayIndex().str();
8664 return result.c_str(); // NOLINT
8665}
8666
8667////////////////////////////////////////////////////////////////////////////////
8668
8669void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8670{
8671 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8672 ASTContext &C = decl->getASTContext();
8673 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8674}
8675
8676//______________________________________________________________________________
8677//
8678// Function Template interface
8679//
8680
8681////////////////////////////////////////////////////////////////////////////////
8682
8683static void ConstructorName(std::string &name, const clang::Decl *decl,
8684 cling::Interpreter &interp,
8685 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8686{
8687 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8688 if (!td) return;
8689
8690 clang::QualType qualType(td->getTypeForDecl(),0);
8691 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8692 unsigned int level = 0;
8693 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8694 if (name[cursor] == '>') ++level;
8695 else if (name[cursor] == '<' && level) --level;
8696 else if (level == 0 && name[cursor] == ':') {
8697 name.erase(0,cursor+1);
8698 break;
8699 }
8700 }
8701}
8702
8703////////////////////////////////////////////////////////////////////////////////
8704
8705void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8706{
8707 output.clear();
8708
8709 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8710 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8711 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8712 }
8713 if (!FD) {
8714 Error("GetFunctionName", "NULL Decl!");
8715 return;
8716 }
8717
8718 // For using-decls, show "Derived", not "Base", i.e. use the
8719 // name of the decl context of the UsingShadowDecl (aka `decl`)
8720 // not the name of FD's decl context.
8721 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8722 {
8724
8725 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8726 {
8728 output.insert(output.begin(), '~');
8729 } else {
8730 llvm::raw_string_ostream stream(output);
8731 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8732 // Don't trigger fopen of the source file to count lines:
8733 printPolicy.AnonymousTagLocations = false;
8734 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8735 }
8736}
8737
8738////////////////////////////////////////////////////////////////////////////////
8739/// Return a unique identifier of the declaration represented by the
8740/// FuncTempInfo
8741
8743{
8744 return (DeclId_t)info;
8745}
8746
8747////////////////////////////////////////////////////////////////////////////////
8748/// Delete the FuncTempInfo_t
8749
8750void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8751{
8752 // Currently the address of ft_info is actually the decl itself,
8753 // so we have nothing to do.
8754}
8755
8756////////////////////////////////////////////////////////////////////////////////
8757/// Construct a FuncTempInfo_t
8758
8759FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8760{
8761 // Currently the address of ft_info is actually the decl itself,
8762 // so we have nothing to do.
8763
8764 return (FuncTempInfo_t*)const_cast<void*>(declid);
8765}
8766
8767////////////////////////////////////////////////////////////////////////////////
8768/// Construct a FuncTempInfo_t
8769
8770FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8771{
8772 // Currently the address of ft_info is actually the decl itself,
8773 // so we have nothing to do.
8774
8775 return (FuncTempInfo_t*)ft_info;
8776}
8777
8778////////////////////////////////////////////////////////////////////////////////
8779/// Check validity of a FuncTempInfo_t
8780
8781Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8782{
8783 // Currently the address of ft_info is actually the decl itself,
8784 // so we have nothing to do.
8785
8786 return t_info != 0;
8787}
8788
8789////////////////////////////////////////////////////////////////////////////////
8790/// Return the maximum number of template arguments of the
8791/// function template described by ft_info.
8792
8793UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8794{
8795 if (!ft_info) return 0;
8796 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8797 return ft->getTemplateParameters()->size();
8798}
8799
8800////////////////////////////////////////////////////////////////////////////////
8801/// Return the number of required template arguments of the
8802/// function template described by ft_info.
8803
8805{
8806 if (!ft_info) return 0;
8807 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8808 return ft->getTemplateParameters()->getMinRequiredArguments();
8809}
8810
8811////////////////////////////////////////////////////////////////////////////////
8812/// Return the property of the function template.
8813
8814Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8815{
8816 if (!ft_info) return 0;
8817
8818 long property = 0L;
8819 property |= kIsCompiled;
8820
8821 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8822
8823 switch (ft->getAccess()) {
8824 case clang::AS_public:
8825 property |= kIsPublic;
8826 break;
8827 case clang::AS_protected:
8828 property |= kIsProtected;
8829 break;
8830 case clang::AS_private:
8831 property |= kIsPrivate;
8832 break;
8833 case clang::AS_none:
8834 if (ft->getDeclContext()->isNamespace())
8836 break;
8837 default:
8838 // IMPOSSIBLE
8839 break;
8840 }
8841
8842 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8843 if (const clang::CXXMethodDecl *md =
8844 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8845 if (md->getMethodQualifiers().hasConst()) {
8846 property |= kIsConstant | kIsConstMethod;
8847 }
8848 if (md->isVirtual()) {
8849 property |= kIsVirtual;
8850 }
8851 if (md->isPure()) {
8852 property |= kIsPureVirtual;
8853 }
8854 if (const clang::CXXConstructorDecl *cd =
8855 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8856 if (cd->isExplicit()) {
8857 property |= kIsExplicit;
8858 }
8859 }
8860 else if (const clang::CXXConversionDecl *cd =
8861 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8862 if (cd->isExplicit()) {
8863 property |= kIsExplicit;
8864 }
8865 }
8866 }
8867 return property;
8868}
8869
8870////////////////////////////////////////////////////////////////////////////////
8871/// Return the property not already defined in Property
8872/// See TDictionary's EFunctionProperty
8873
8874Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8875{
8876 if (!ft_info) return 0;
8877
8878 long property = 0L;
8879 property |= kIsCompiled;
8880
8881 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8882 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8883
8884 if (fd->isOverloadedOperator())
8886 if (llvm::isa<clang::CXXConversionDecl>(fd))
8888 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8890 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8892 if (fd->isInlined())
8894 return property;
8895}
8896
8897////////////////////////////////////////////////////////////////////////////////
8898/// Return the name of this function template.
8899
8900void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8901{
8902 output.Clear();
8903 if (!ft_info) return;
8904 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8905 std::string buf;
8906 GetFunctionName(ft->getTemplatedDecl(), buf);
8907 output = buf;
8908}
8909
8910////////////////////////////////////////////////////////////////////////////////
8911/// Return the comments associates with this function template.
8912
8913void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8914{
8915 output.Clear();
8916 if (!ft_info) return;
8917 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8918
8919 // Iterate over the redeclarations, we can have multiple definitions in the
8920 // redecl chain (came from merging of pcms).
8921 if (const RedeclarableTemplateDecl *AnnotFD
8922 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8923 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8924 output = A->getAnnotation().str();
8925 return;
8926 }
8927 }
8928 if (!ft->isFromASTFile()) {
8929 // Try to get the comment from the header file if present
8930 // but not for decls from AST file, where rootcling would have
8931 // created an annotation
8933 }
8934}
8935
8936
8937//______________________________________________________________________________
8938//
8939// MethodInfo interface
8940//
8941
8942////////////////////////////////////////////////////////////////////////////////
8943/// Interface to cling function
8944
8945void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8946{
8947 delete(TClingMethodInfo*) minfo;
8948}
8949
8950////////////////////////////////////////////////////////////////////////////////
8951
8952void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8953{
8954 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8955 info->CreateSignature(signature);
8956}
8957
8958////////////////////////////////////////////////////////////////////////////////
8959
8960MethodInfo_t* TCling::MethodInfo_Factory() const
8961{
8963 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8964}
8965
8966////////////////////////////////////////////////////////////////////////////////
8967
8968MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8969{
8971 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8972}
8973
8974////////////////////////////////////////////////////////////////////////////////
8975
8976MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8977{
8978 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8980 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
8981}
8982
8983////////////////////////////////////////////////////////////////////////////////
8984
8985MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
8986{
8987 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8988}
8989
8990////////////////////////////////////////////////////////////////////////////////
8991
8992void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
8993{
8994 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8995 return info->InterfaceMethod();
8996}
8997
8998////////////////////////////////////////////////////////////////////////////////
8999
9000bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9001{
9002 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9003 return info->IsValid();
9004}
9005
9006////////////////////////////////////////////////////////////////////////////////
9007
9008int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9009{
9010 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9011 return info->NArg();
9012}
9013
9014////////////////////////////////////////////////////////////////////////////////
9015
9016int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9017{
9018 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9019 return info->NDefaultArg();
9020}
9021
9022////////////////////////////////////////////////////////////////////////////////
9023
9024int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9025{
9026 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9027 return info->Next();
9028}
9029
9030////////////////////////////////////////////////////////////////////////////////
9031
9032Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9033{
9034 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9035 return info->Property();
9036}
9037
9038////////////////////////////////////////////////////////////////////////////////
9039
9041{
9042 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9043 return info->ExtraProperty();
9044}
9045
9046////////////////////////////////////////////////////////////////////////////////
9047
9048TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9049{
9050 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9051 return (TypeInfo_t*)info->Type();
9052}
9053
9054////////////////////////////////////////////////////////////////////////////////
9055
9056const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9057{
9058 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9059 TTHREAD_TLS_DECL(TString, mangled_name);
9060 mangled_name = info->GetMangledName();
9061 return mangled_name;
9062}
9063
9064////////////////////////////////////////////////////////////////////////////////
9065
9066const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9067{
9068 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9069 return info->GetPrototype();
9070}
9071
9072////////////////////////////////////////////////////////////////////////////////
9073
9074const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9075{
9076 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9077 return info->Name();
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081
9082const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9083{
9084 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9085 return info->TypeName();
9086}
9087
9088////////////////////////////////////////////////////////////////////////////////
9089
9090std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9091{
9092 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9093 if (info && info->IsValid())
9094 return info->Type()->NormalizedName(*fNormalizedCtxt);
9095 else
9096 return "";
9097}
9098
9099////////////////////////////////////////////////////////////////////////////////
9100
9101const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9102{
9103 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9104 return info->Title();
9105}
9106
9107////////////////////////////////////////////////////////////////////////////////
9108
9110{
9111 if (func) {
9112 return MethodInfo_MethodCallReturnType(func->fInfo);
9113 } else {
9114 return EReturnType::kOther;
9115 }
9116}
9117
9118////////////////////////////////////////////////////////////////////////////////
9119
9121{
9122 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9123 if (info && info->IsValid()) {
9124 TClingTypeInfo *typeinfo = info->Type();
9125 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9126 if (QT->isEnumeralType()) {
9127 return EReturnType::kLong;
9128 } else if (QT->isPointerType()) {
9129 // Look for char*
9130 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9131 if ( QT->isCharType() ) {
9132 return EReturnType::kString;
9133 } else {
9134 return EReturnType::kOther;
9135 }
9136 } else if ( QT->isFloatingType() ) {
9137 int sz = typeinfo->Size();
9138 if (sz == 4 || sz == 8) {
9139 // Support only float and double.
9140 return EReturnType::kDouble;
9141 } else {
9142 return EReturnType::kOther;
9143 }
9144 } else if ( QT->isIntegerType() ) {
9145 int sz = typeinfo->Size();
9146 if (sz <= 8) {
9147 // Support only up to long long ... but
9148 // FIXME the TMethodCall::Execute only
9149 // return long (4 bytes) ...
9150 // The v5 implementation of TMethodCall::ReturnType
9151 // was not making the distinction so we let it go
9152 // as is for now, but we really need to upgrade
9153 // TMethodCall::Execute ...
9154 return EReturnType::kLong;
9155 } else {
9156 return EReturnType::kOther;
9157 }
9158 } else {
9159 return EReturnType::kOther;
9160 }
9161 } else {
9162 return EReturnType::kOther;
9163 }
9164}
9165
9166//______________________________________________________________________________
9167//
9168// MethodArgInfo interface
9169//
9170
9171////////////////////////////////////////////////////////////////////////////////
9172
9173void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9174{
9175 delete(TClingMethodArgInfo*) marginfo;
9176}
9177
9178////////////////////////////////////////////////////////////////////////////////
9179
9180MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9181{
9183 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9184}
9185
9186////////////////////////////////////////////////////////////////////////////////
9187
9188MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9189{
9191 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9192}
9193
9194////////////////////////////////////////////////////////////////////////////////
9195
9196MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9197{
9198 return (MethodArgInfo_t*)
9200}
9201
9202////////////////////////////////////////////////////////////////////////////////
9203
9204bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9205{
9206 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9207 return info->IsValid();
9208}
9209
9210////////////////////////////////////////////////////////////////////////////////
9211
9212int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9213{
9214 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9215 return info->Next();
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219
9220Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9221{
9222 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9223 return info->Property();
9224}
9225
9226////////////////////////////////////////////////////////////////////////////////
9227
9228const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9229{
9230 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9231 return info->DefaultValue();
9232}
9233
9234////////////////////////////////////////////////////////////////////////////////
9235
9236const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9237{
9238 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9239 return info->Name();
9240}
9241
9242////////////////////////////////////////////////////////////////////////////////
9243
9244const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9245{
9246 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9247 return info->TypeName();
9248}
9249
9250////////////////////////////////////////////////////////////////////////////////
9251
9252std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9253{
9254 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9255 return info->Type()->NormalizedName(*fNormalizedCtxt);
9256}
9257
9258//______________________________________________________________________________
9259//
9260// TypeInfo interface
9261//
9262
9263////////////////////////////////////////////////////////////////////////////////
9264
9265void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9266{
9267 delete (TClingTypeInfo*) tinfo;
9268}
9269
9270////////////////////////////////////////////////////////////////////////////////
9271
9272TypeInfo_t* TCling::TypeInfo_Factory() const
9273{
9275 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9276}
9277
9278////////////////////////////////////////////////////////////////////////////////
9279
9280TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9281{
9283 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9284}
9285
9286////////////////////////////////////////////////////////////////////////////////
9287
9288TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9289{
9290 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9291}
9292
9293////////////////////////////////////////////////////////////////////////////////
9294
9295void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9296{
9298 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9299 TClinginfo->Init(name);
9300}
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9304bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9305{
9306 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9307 return TClinginfo->IsValid();
9308}
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9312const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9313{
9314 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9315 return TClinginfo->Name();
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319
9320Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9321{
9322 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9323 return TClinginfo->Property();
9324}
9325
9326////////////////////////////////////////////////////////////////////////////////
9327
9328int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9329{
9330 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9331 return TClinginfo->RefType();
9332}
9333
9334////////////////////////////////////////////////////////////////////////////////
9335
9336int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9337{
9338 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9339 return TClinginfo->Size();
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343
9344const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9345{
9346 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9347 return TClinginfo->TrueName(*fNormalizedCtxt);
9348}
9349
9350
9351//______________________________________________________________________________
9352//
9353// TypedefInfo interface
9354//
9355
9356////////////////////////////////////////////////////////////////////////////////
9357
9358void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9359{
9360 delete(TClingTypedefInfo*) tinfo;
9361}
9362
9363////////////////////////////////////////////////////////////////////////////////
9364
9365TypedefInfo_t* TCling::TypedefInfo_Factory() const
9366{
9368 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9369}
9370
9371////////////////////////////////////////////////////////////////////////////////
9372
9373TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9374{
9376 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9377}
9378
9379////////////////////////////////////////////////////////////////////////////////
9380
9381TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9382{
9383 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9384}
9385
9386////////////////////////////////////////////////////////////////////////////////
9387
9388void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9389 const char* name) const
9390{
9392 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9393 TClinginfo->Init(name);
9394}
9395
9396////////////////////////////////////////////////////////////////////////////////
9397
9398bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9399{
9400 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9401 return TClinginfo->IsValid();
9402}
9403
9404////////////////////////////////////////////////////////////////////////////////
9405
9406Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9407{
9408 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9409 return TClinginfo->Next();
9410}
9411
9412////////////////////////////////////////////////////////////////////////////////
9413
9414Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9415{
9416 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9417 return TClinginfo->Property();
9418}
9419
9420////////////////////////////////////////////////////////////////////////////////
9421
9422int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9423{
9424 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9425 return TClinginfo->Size();
9426}
9427
9428////////////////////////////////////////////////////////////////////////////////
9429
9430const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9431{
9432 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9433 return TClinginfo->TrueName(*fNormalizedCtxt);
9434}
9435
9436////////////////////////////////////////////////////////////////////////////////
9437
9438const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9439{
9440 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9441 return TClinginfo->Name();
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445
9446const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9447{
9448 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9449 return TClinginfo->Title();
9450}
9451
9452////////////////////////////////////////////////////////////////////////////////
9453
9455{
9456 if (!fInitialMutex) {
9458 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9459 }
9461 }
9462 // We will "forget" this lock once we backed out of all interpreter frames.
9463 // Here we are entering one, so ++.
9465}
9466
9467////////////////////////////////////////////////////////////////////////////////
9468
9470{
9471 if (!fInitialMutex)
9472 return;
9473 if (fInitialMutex.fRecurseCount == 0) {
9474 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9475 }
9476 else if (--fInitialMutex.fRecurseCount == 0) {
9477 // We have returned from all interpreter frames. Reset the initial lock state.
9478 fInitialMutex.fState.reset();
9479 }
9480}
9481
9482////////////////////////////////////////////////////////////////////////////////
9483/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9484
9486{
9487 if (gInterpreterMutex) {
9488 if (delta) {
9489 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9490 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9491 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9492 // Now that we have the lock, update the global
9493 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9494 std::swap(fInitialMutex, typedDelta->fInitialState);
9495 } else {
9496 // This case happens when EnableThreadSafety is first called from
9497 // the interpreter function we just handled.
9498 // Since thread safety was not enabled at the time we rewound, there was
9499 // no lock taken and even-though we should be locking the rest of this
9500 // interpreter handling/modifying code (since there might be threads in
9501 // flight), we can't because there would not be any lock guard to release the
9502 // locks
9504 Error("ApplyToInterpreterMutex",
9505 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9506 "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.");
9507 }
9508 }
9509}
9510
9511////////////////////////////////////////////////////////////////////////////////
9512/// Reset the interpreter lock to the state it had before interpreter-related
9513/// calls happened.
9514
9516{
9517 if (fInitialMutex) {
9518 // Need to start a new recurse count.
9519 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9520 std::swap(uniqueP->fInitialState, fInitialMutex);
9521 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9522 return uniqueP.release();
9523 }
9525 return nullptr;
9526}
#define R__EXTERN
Definition DllImport.h:27
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
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
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
unsigned long ULong_t
Definition RtypesCore.h:55
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:339
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:577
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1334
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7201
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:6953
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:572
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:899
R__EXTERN int optind
Definition TCling.cxx:315
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:366
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:567
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:555
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:331
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:222
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3890
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:349
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1979
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3124
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition TCling.cxx:3932
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1087
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:908
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:1072
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:377
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:631
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1704
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:626
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:219
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:697
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1086
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:249
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:591
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:562
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:602
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3908
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:586
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:387
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:213
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:642
#define R__DLLEXPORT
Definition TCling.cxx:150
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:358
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:231
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:621
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1037
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1190
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8683
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:324
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:2463
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:7110
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:234
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:678
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:2004
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:606
const char * fantomline
Definition TCling.cxx:846
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:581
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6292
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5476
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:216
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:598
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:1059
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:637
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:614
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7222
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:649
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:386
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:117
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:230
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:197
const Int_t kWarning
Definition TError.cxx:37
Int_t gErrorIgnoreLevel
Definition TError.cxx:43
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:241
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:256
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:585
#define gROOT
Definition TROOT.h:405
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
@ kReadPermission
Definition TSystem.h:47
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:118
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17502
#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)
long long ExecInt64(void *address)
void SetArg(long arg)
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
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:1013
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1021
std::string fContent
Definition TCling.h:605
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:6164
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9228
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8246
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9312
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:8992
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4356
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3870
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9398
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6225
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7884
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:3633
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6528
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7405
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7810
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9048
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7787
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:7448
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3709
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8669
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:494
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:6848
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9032
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4403
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8280
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8602
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7531
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:4450
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3754
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8272
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6722
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9328
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4332
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8159
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9074
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8416
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4003
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7461
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7238
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9120
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7658
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3545
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9000
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8759
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9272
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7500
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6833
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7622
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7607
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3333
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9446
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:8009
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5615
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:6483
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1851
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4468
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1658
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7711
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2659
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8436
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6595
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7861
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7845
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7910
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5427
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3167
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3857
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7876
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9485
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6551
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:4687
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:8075
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3133
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:7427
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8528
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8562
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3650
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:5492
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8296
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7552
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9204
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9336
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3768
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7435
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7588
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:8793
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:5119
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9365
TObjArray * fRootmapFiles
Definition TCling.h:126
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2493
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8344
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9244
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:630
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5367
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8586
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9438
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8409
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9040
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3537
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7049
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8770
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8578
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8781
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:2673
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8231
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3668
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8626
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4914
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:7966
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8056
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9515
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9236
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3142
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9388
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8650
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7829
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3080
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:7482
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:7305
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7868
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9381
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:5012
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:2433
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9252
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:4796
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9220
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9422
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7818
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:5164
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:620
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6702
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3500
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9406
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:4971
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9295
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7542
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8618
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8386
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8642
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5442
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
void ForgetMutexState() final
Definition TCling.cxx:9469
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9024
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8120
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:8945
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9173
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8543
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8151
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:6070
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5958
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8213
std::set< TClass * > & GetModTClasses()
Definition TCling.h:565
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8481
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7837
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8336
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8460
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:419
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5349
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7291
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7368
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6908
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8814
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:467
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9344
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:5976
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7631
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6946
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9212
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9454
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9320
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9066
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:8804
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:2050
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6116
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:8952
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4312
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6931
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:2424
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8570
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8239
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9016
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4459
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5885
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:7561
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9056
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
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:577
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:5074
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8304
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7359
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8705
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4484
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7350
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9196
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8452
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:4140
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7397
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3400
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9265
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9008
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4905
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9109
void ProcessClassesToUpdate()
Definition TCling.cxx:2020
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:5097
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:4926
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9101
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8515
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:3093
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8497
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:7974
int UnloadFile(const char *path) const final
Definition TCling.cxx:7594
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7794
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8874
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7893
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8507
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8658
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4505
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1030
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4836
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5197
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8264
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8352
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8473
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:7982
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4439
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8360
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8913
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8394
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3844
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1736
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6587
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:3725
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7614
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:3739
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7469
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3570
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5897
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3877
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8536
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:5380
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:4477
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:2688
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6038
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:8985
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7902
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9180
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6696
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:4993
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8128
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8255
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8750
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:5141
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3783
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8594
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7853
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:8960
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8610
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3072
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:631
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2482
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:7492
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2398
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9358
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3693
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9430
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7513
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8368
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:6341
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9082
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7918
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7319
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6806
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6638
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1676
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:8189
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:4735
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:8900
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9304
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1946
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9090
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8378
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4515
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8197
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3116
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9288
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8205
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8143
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:8634
virtual void ShutDown() final
Definition TCling.cxx:1695
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3884
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9414
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1718
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:3554
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:4953
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6711
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5701
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8489
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6938
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
const char * GetName() const override
Returns name of object.
Definition TEnv.h:109
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 a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:51
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:357
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:956
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:774
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:970
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:998
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:944
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetBinDir()
Get the binary directory in the installation. Static utility function.
Definition TROOT.cxx:2932
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:2974
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2729
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2895
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:2984
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2905
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition TROOT.cxx:2953
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:421
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2222
const char * Data() const
Definition TString.h:380
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:924
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2242
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:627
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:418
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:576
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:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
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:1277
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:848
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:839
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1666
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3966
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4251
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1074
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1539
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1858
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:1401
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1084
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:1299
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:856
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2490
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:937
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1796
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2035
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:440
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition TSystem.cxx:2831
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:874
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1549
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1650
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:890
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1035
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:737
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2021
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()
bool CanConvertEnvValueToBool(const std::string &value)
bool ConvertEnvValueToBool(const std::string &value)
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a 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...
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.
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=0)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
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:196
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:189
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:191
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:218
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 *)
Definition file.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
Long_t fMemVirtual
Definition TSystem.h:196
Long_t fMemResident
Definition TSystem.h:195
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()