Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include "llvm/IR/GlobalValue.h"
119#include "llvm/IR/Module.h"
120
121#include "llvm/Support/DynamicLibrary.h"
122#include "llvm/Support/raw_ostream.h"
123#include "llvm/Support/Path.h"
124#include "llvm/Support/Process.h"
125#include "llvm/Object/ELFObjectFile.h"
126#include "llvm/Object/ObjectFile.h"
127#include "llvm/Object/SymbolicFile.h"
128#include "llvm/Support/FileSystem.h"
129
130#include <algorithm>
131#include <iostream>
132#include <cassert>
133#include <map>
134#include <set>
135#include <stdexcept>
136#include <stdint.h>
137#include <fstream>
138#include <sstream>
139#include <string>
140#include <tuple>
141#include <typeinfo>
142#include <unordered_map>
143#include <unordered_set>
144#include <utility>
145#include <vector>
146#include <functional>
147#include <optional>
148
149#ifndef R__WIN32
150#include <cxxabi.h>
151#define R__DLLEXPORT __attribute__ ((visibility ("default")))
152#include <sys/stat.h>
153#endif
154#include <limits.h>
155#include <stdio.h>
156
157#ifdef __APPLE__
158#include <dlfcn.h>
159#include <mach-o/dyld.h>
160#include <mach-o/loader.h>
161#endif // __APPLE__
162
163#ifdef R__UNIX
164#include <dlfcn.h>
165#endif
166
167#if defined(R__LINUX) || defined(R__FBSD)
168# ifndef _GNU_SOURCE
169# define _GNU_SOURCE
170# endif
171# include <link.h> // dl_iterate_phdr()
172#endif
173
174#if defined(__CYGWIN__)
175#include <sys/cygwin.h>
176#define HMODULE void *
177extern "C" {
178 __declspec(dllimport) void * __stdcall GetCurrentProcess();
179 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
180 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
181}
182#endif
183
184// Fragment copied from LLVM's raw_ostream.cpp
185#if defined(_MSC_VER)
186#ifndef STDIN_FILENO
187# define STDIN_FILENO 0
188#endif
189#ifndef STDOUT_FILENO
190# define STDOUT_FILENO 1
191#endif
192#ifndef STDERR_FILENO
193# define STDERR_FILENO 2
194#endif
195#ifndef R__WIN32
196//#if defined(HAVE_UNISTD_H)
197# include <unistd.h>
198//#endif
199#else
200#include "Windows4Root.h"
201#include <Psapi.h>
202#include <direct.h>
203#undef GetModuleFileName
204#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
205#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
206#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
207#define dlclose(library) ::FreeLibrary((HMODULE)library)
208#define R__DLLEXPORT __declspec(dllexport)
209#endif
210#endif
211
212//______________________________________________________________________________
213// These functions are helpers for debugging issues with non-LLVMDEV builds.
214//
215R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
216 return D->getDeclContext();
217}
218R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
219 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
220}
221R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::RecordDecl>(DC);
223}
224R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
225 return DC->dumpDeclContext();
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
228 return D->dump();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
231 return FD->dump();
232}
234 return ((clang::Decl*)D)->dump();
235}
237 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
238 std::string name;
239 {
240 llvm::raw_string_ostream OS(name);
241 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
242 true /*Qualified*/);
243 }
244 printf("%s\n", name.c_str());
245 }
246}
247//______________________________________________________________________________
248// These functions are helpers for testing issues directly rather than
249// relying on side effects.
250// This is used for the test for ROOT-7462/ROOT-6070
252 return D->isInvalidDecl();
253}
256 assert(info && info->IsValid());
257 return info->GetDecl()->isInvalidDecl();
258}
259
260using std::string, std::vector;
261using namespace clang;
262using namespace ROOT;
263
264namespace {
265 static const std::string gInterpreterClassDef = R"ICF(
266#undef ClassDef
267#define ClassDef(name, id) \
268_ClassDefInterp_(name,id,virtual,) \
269static int DeclFileLine() { return __LINE__; }
270#undef ClassDefNV
271#define ClassDefNV(name, id) \
272_ClassDefInterp_(name,id,,) \
273static int DeclFileLine() { return __LINE__; }
274#undef ClassDefOverride
275#define ClassDefOverride(name, id) \
276_ClassDefInterp_(name,id,,override) \
277static int DeclFileLine() { return __LINE__; }
278)ICF";
279
280 static const std::string gNonInterpreterClassDef = R"ICF(
281#define __ROOTCLING__ 1
282#undef ClassDef
283#define ClassDef(name,id) \
284_ClassDefOutline_(name,id,virtual,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefNV
287#define ClassDefNV(name, id)\
288_ClassDefOutline_(name,id,,)\
289static int DeclFileLine() { return __LINE__; }
290#undef ClassDefOverride
291#define ClassDefOverride(name, id)\
292_ClassDefOutline_(name,id,,override)\
293static int DeclFileLine() { return __LINE__; }
294)ICF";
295
296// The macros below use ::Error, so let's ensure it is included
297 static const std::string gClassDefInterpMacro = R"ICF(
298#include "TError.h"
299
300#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
301private: \
302public: \
303 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
304 static const char *Class_Name() { return #name; } \
305 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
306 static Version_t Class_Version() { return id; } \
307 static TClass *Dictionary() { return 0; } \
308 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
309 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
310 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
311 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
312 static const char *DeclFileName() { return __FILE__; } \
313 static int ImplFileLine() { return 0; } \
314 static const char *ImplFileName() { return __FILE__; }
315)ICF";
316}
318
319// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
320// ROOT (which uses rtti)
321
322////////////////////////////////////////////////////////////////////////////////
323/// Print a StackTrace!
324
325extern "C"
327 gSystem->StackTrace();
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load a library.
332
333extern "C" int TCling__LoadLibrary(const char *library)
334{
335 return gSystem->Load(library, "", false);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
340
341extern "C" void TCling__RestoreInterpreterMutex(void *delta)
342{
343 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
348/// which is extracted by error messages we get from callback from cling. Return true
349/// when the missing library was autoloaded.
350
351extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
352{
353 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Reset the interpreter lock to the state it had before interpreter-related
358/// calls happened.
359
361{
362 return ((TCling*)gCling)->RewindInterpreterMutex();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Lock the interpreter.
367
369{
370 if (gInterpreterMutex) {
371 gInterpreterMutex->Lock();
372 }
373 return nullptr;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Unlock the interpreter.
378
380{
381 if (gInterpreterMutex) {
382 gInterpreterMutex->UnLock();
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
388
389static void TCling__UpdateClassInfo(const NamedDecl* TD)
390{
391 static Bool_t entered = kFALSE;
392 static vector<const NamedDecl*> updateList;
393 Bool_t topLevel;
394
395 if (entered) topLevel = kFALSE;
396 else {
397 entered = kTRUE;
398 topLevel = kTRUE;
399 }
400 if (topLevel) {
401 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
402 } else {
403 // If we are called indirectly from within another call to
404 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
405 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
406 // This allows for the dictionary to be fully populated when we actually
407 // update the TClass object. The updating of the TClass sometimes
408 // (STL containers and when there is an emulated class) forces the building
409 // of the TClass object's real data (which needs the dictionary info).
410 updateList.push_back(TD);
411 }
412 if (topLevel) {
413 while (!updateList.empty()) {
414 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
415 updateList.pop_back();
416 }
417 entered = kFALSE;
418 }
419}
420
421void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
422 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
423 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
424 // Add the constants to the enum type.
425 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
426 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
427 // Get name of the enum type.
428 std::string constbuf;
429 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
430 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
431 llvm::raw_string_ostream stream(constbuf);
432 // Don't trigger fopen of the source file to count lines:
433 Policy.AnonymousTagLocations = false;
434 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
435 }
436 const char* constantName = constbuf.c_str();
437
438 // Get value of the constant.
440 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
441 if (valAPSInt.isSigned()) {
442 value = valAPSInt.getSExtValue();
443 } else {
444 value = valAPSInt.getZExtValue();
445 }
446
447 // Create the TEnumConstant or update it if existing
448 TEnumConstant* enumConstant = nullptr;
449 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
450 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
451 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
452 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
453 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
454 } else {
455 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
456 }
457
458 // Add the global constants to the list of Globals.
459 if (!cl) {
460 TCollection* globals = gROOT->GetListOfGlobals(false);
461 if (!globals->FindObject(constantName)) {
462 globals->Add(enumConstant);
463 }
464 }
465 }
466 }
467}
468
469TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
470{
471 // Handle new enum declaration for either global and nested enums.
472
473 // Create the enum type.
474 TEnum* enumType = nullptr;
475 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
476 std::string buf;
477 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
478 // Get name of the enum type.
479 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
480 llvm::raw_string_ostream stream(buf);
481 // Don't trigger fopen of the source file to count lines:
482 Policy.AnonymousTagLocations = false;
483 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
484 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
485 }
486 if (buf.empty()) {
487 return nullptr;
488 }
489 const char* name = buf.c_str();
490 enumType = new TEnum(name, VD, cl);
491 UpdateEnumConstants(enumType, cl);
492
493 return enumType;
494}
495
496void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
497 // Handle new declaration.
498 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
499
500 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
501
502 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
503 && !dyn_cast<clang::RecordDecl>(D)) return;
504
505 if (isa<clang::FunctionDecl>(D->getDeclContext())
506 || isa<clang::TagDecl>(D->getDeclContext()))
507 return;
508
509 // Don't list templates.
510 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
511 if (RD->getDescribedClassTemplate())
512 return;
513 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
514 if (FD->getDescribedFunctionTemplate())
515 return;
516 }
517
518 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
519 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
521 }
522 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
523
524 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
525 // Mostly just for EnumDecl (the other TagDecl are handled
526 // by the 'RecordDecl' if statement.
528 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
530 }
531
532 // We care about declarations on the global scope.
533 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
534 return;
535
536 // Enums are lazyly created, thus we don not need to handle them here.
537 if (isa<EnumDecl>(ND))
538 return;
539
540 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
541 // scope.
542 if (!(isa<VarDecl>(ND)))
543 return;
544
545 // Skip if already in the list.
546 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
547 return;
548
549 // Put the global constants and global enums in the corresponding lists.
550 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
552 cast<ValueDecl>(ND), nullptr)));
553 }
554}
555
556extern "C"
558{
559 // We are sure in this context of the type of the interpreter
560 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
561}
562
563extern "C"
564void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
565 ((TCling*)gCling)->UpdateListsOnCommitted(T);
566}
567
568extern "C"
569void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
570 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
571}
572
573extern "C"
574void TCling__InvalidateGlobal(const clang::Decl *D) {
575 ((TCling*)gCling)->InvalidateGlobal(D);
576}
577
578extern "C"
579void TCling__TransactionRollback(const cling::Transaction &T) {
580 ((TCling*)gCling)->TransactionRollback(T);
581}
582
583extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
584 const char* canonicalName) {
585 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
586}
587
588extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
589{
590 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
591}
592
593extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
594 const char* canonicalName) {
595 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
596}
597
598
599extern "C"
600TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
601 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
602}
603
604extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
605 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
606}
607
608extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
609 const char* argv[])
610{
611 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
612
613 return tcling;
614}
615
617{
618 delete interp;
619}
620
621// Load library containing specified class. Returns 0 in case of error
622// and 1 in case if success.
623extern "C" int TCling__AutoLoadCallback(const char* className)
624{
625 return ((TCling*)gCling)->AutoLoad(className);
626}
627
628extern "C" int TCling__AutoParseCallback(const char* className)
629{
630 return ((TCling*)gCling)->AutoParse(className);
631}
632
633extern "C" const char* TCling__GetClassSharedLibs(const char* className)
634{
635 return ((TCling*)gCling)->GetClassSharedLibs(className);
636}
637
638// Returns 0 for failure 1 for success
639extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
640{
641 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
642}
643
644extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
645{
646 string file(fileName);
647 string opt(options);
648 return gSystem->CompileMacro(file.c_str(), opt.c_str());
649}
650
651extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
652 string &args, string &io, string &fname)
653{
654 string file(fileName);
655 TString f, amode, arguments, aclicio;
656 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
657 mode = amode.Data(); args = arguments.Data();
658 io = aclicio.Data(); fname = f.Data();
659}
660
661//______________________________________________________________________________
662//
663//
664//
665
666#ifdef R__WIN32
667extern "C" {
668 char *__unDName(char *demangled, const char *mangled, int out_len,
669 void * (* pAlloc )(size_t), void (* pFree )(void *),
670 unsigned short int flags);
671}
672#endif
673
674////////////////////////////////////////////////////////////////////////////////
675/// Find a template decl within N nested namespaces, 0<=N<inf
676/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
677/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
678/// Returns nullptr in case of error
679
680static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
681{
682 using namespace clang;
683 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
684 return FindTemplateInNamespace(*nsd->decls_begin());
685 }
686
687 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
688 return ctd;
689 }
690
691 return nullptr; // something went wrong.
692}
693
694//______________________________________________________________________________
695//
696//
697//
698
699int TCling_GenerateDictionary(const std::vector<std::string> &classes,
700 const std::vector<std::string> &headers,
701 const std::vector<std::string> &fwdDecls,
702 const std::vector<std::string> &unknown)
703{
704 //This function automatically creates the "LinkDef.h" file for templated
705 //classes then executes CompileMacro on it.
706 //The name of the file depends on the class name, and it's not generated again
707 //if the file exist.
708 if (classes.empty()) {
709 return 0;
710 }
711 // Use the name of the first class as the main name.
712 const std::string& className = classes[0];
713 //(0) prepare file name
714 TString fileName = "AutoDict_";
715 std::string::const_iterator sIt;
716 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
717 if (*sIt == '<' || *sIt == '>' ||
718 *sIt == ' ' || *sIt == '*' ||
719 *sIt == ',' || *sIt == '&' ||
720 *sIt == ':') {
721 fileName += '_';
722 }
723 else {
724 fileName += *sIt;
725 }
726 }
727 if (classes.size() > 1) {
728 Int_t chk = 0;
729 std::vector<std::string>::const_iterator it = classes.begin();
730 while ((++it) != classes.end()) {
731 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
732 chk = chk * 3 + it->at(cursor);
733 }
734 }
735 fileName += TString::Format("_%u", chk);
736 }
737 fileName += ".cxx";
738 if (gSystem->AccessPathName(fileName) != 0) {
739 //file does not exist
740 //(1) prepare file data
741 // If STL, also request iterators' operators.
742 // vector is special: we need to check whether
743 // vector::iterator is a typedef to pointer or a
744 // class.
745 static const std::set<std::string> sSTLTypes {
746 "vector","list","forward_list","deque","map","unordered_map","multimap",
747 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
748 "queue","priority_queue","stack","iterator"};
749 std::vector<std::string>::const_iterator it;
750 std::string fileContent("");
751 for (it = headers.begin(); it != headers.end(); ++it) {
752 fileContent += "#include \"" + *it + "\"\n";
753 }
754 for (it = unknown.begin(); it != unknown.end(); ++it) {
755 TClass* cl = TClass::GetClass(it->c_str());
756 if (cl && cl->GetDeclFileName()) {
757 TString header = gSystem->BaseName(cl->GetDeclFileName());
758 TString dir = gSystem->GetDirName(cl->GetDeclFileName());
759 TString dirbase(gSystem->BaseName(dir));
760 while (dirbase.Length() && dirbase != "."
761 && dirbase != "include" && dirbase != "inc"
762 && dirbase != "prec_stl") {
763 gSystem->PrependPathName(dirbase, header);
764 dir = gSystem->GetDirName(dir);
765 }
766 fileContent += TString("#include \"") + header + "\"\n";
767 }
768 }
769 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
770 fileContent += "class " + *it + ";\n";
771 }
772 fileContent += "#ifdef __CLING__ \n";
773 fileContent += "#pragma link C++ nestedclasses;\n";
774 fileContent += "#pragma link C++ nestedtypedefs;\n";
775 for (it = classes.begin(); it != classes.end(); ++it) {
776 std::string n(*it);
777 size_t posTemplate = n.find('<');
778 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
779 if (posTemplate != std::string::npos) {
780 n.erase(posTemplate, std::string::npos);
781 if (n.compare(0, 5, "std::") == 0) {
782 n.erase(0, 5);
783 }
784 iSTLType = sSTLTypes.find(n);
785 }
786 fileContent += "#pragma link C++ class ";
787 fileContent += *it + "+;\n" ;
788 fileContent += "#pragma link C++ class ";
789 if (iSTLType != sSTLTypes.end()) {
790 // STL class; we cannot (and don't need to) store iterators;
791 // their shadow and the compiler's version don't agree. So
792 // don't ask for the '+'
793 fileContent += *it + "::*;\n" ;
794 }
795 else {
796 // Not an STL class; we need to allow the I/O of contained
797 // classes (now that we have a dictionary for them).
798 fileContent += *it + "::*+;\n" ;
799 }
800 }
801 fileContent += "#endif\n";
802 //end(1)
803 //(2) prepare the file
804 FILE* filePointer;
805 filePointer = fopen(fileName, "w");
806 if (filePointer == nullptr) {
807 //can't open a file
808 return 1;
809 }
810 //end(2)
811 //write data into the file
812 fprintf(filePointer, "%s", fileContent.c_str());
813 fclose(filePointer);
814 }
815 //(3) checking if we can compile a macro, if not then cleaning
816 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
817 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
818 Int_t ret = gSystem->CompileMacro(fileName, "k");
819 gErrorIgnoreLevel = oldErrorIgnoreLevel;
820 if (ret == 0) { //can't compile a macro
821 return 2;
822 }
823 //end(3)
824 return 0;
825}
826
827int TCling_GenerateDictionary(const std::string& className,
828 const std::vector<std::string> &headers,
829 const std::vector<std::string> &fwdDecls,
830 const std::vector<std::string> &unknown)
831{
832 //This function automatically creates the "LinkDef.h" file for templated
833 //classes then executes CompileMacro on it.
834 //The name of the file depends on the class name, and it's not generated again
835 //if the file exist.
836 std::vector<std::string> classes;
837 classes.push_back(className);
838 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
839}
840
841//______________________________________________________________________________
842//
843//
844//
845
846// It is a "fantom" method to synchronize user keyboard input
847// and ROOT prompt line (for WIN32)
848const char* fantomline = "TRint::EndOfLineAction();";
849
850//______________________________________________________________________________
851//
852//
853//
854
855void* TCling::fgSetOfSpecials = nullptr;
856
857//______________________________________________________________________________
858//
859// llvm error handler through exceptions; see also cling/UserInterface
860//
861namespace {
862 // Handle fatal llvm errors by throwing an exception.
863 // Yes, throwing exceptions in error handlers is bad.
864 // Doing nothing is pretty terrible, too.
865 void exceptionErrorHandler(void * /*user_data*/,
866 const char *reason,
867 bool /*gen_crash_diag*/) {
868 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
869 }
870}
871
872//______________________________________________________________________________
873//
874//
875//
876
877////////////////////////////////////////////////////////////////////////////////
878
879namespace{
880 // An instance of this class causes the diagnostics of clang to be suppressed
881 // during its lifetime
882 class clangDiagSuppr {
883 public:
884 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
885 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
886 fDiagEngine.setIgnoreAllWarnings(true);
887 }
888
889 ~clangDiagSuppr() {
890 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
891 }
892 private:
893 clang::DiagnosticsEngine& fDiagEngine;
894 bool fOldDiagValue;
895 };
896
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Allow calling autoparsing from TMetaUtils
902{
903 return gCling->AutoParse(cname);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Try hard to avoid looking up in the Cling database as this could enduce
908/// an unwanted autoparsing.
909
910bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
911 std::string &result)
912{
913 result.clear();
914
915 unsigned long offset = 0;
916 if (strncmp(tname.c_str(), "const ", 6) == 0) {
917 offset = 6;
918 }
919 unsigned long end = tname.length();
920 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
921 if ( tname[end-1]==']' ) {
922 --end;
923 while ( end && tname[end-1]!='[' ) --end;
924 }
925 --end;
926 }
927 std::string innerbuf;
928 const char *inner;
929 if (end != tname.length()) {
930 innerbuf = tname.substr(offset,end-offset);
931 inner = innerbuf.c_str();
932 } else {
933 inner = tname.c_str()+offset;
934 }
935
936 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
937 if (gROOT->GetListOfClasses()->FindObject(inner)
938 || TClassTable::Check(inner,result) ) {
939 // This is a known class.
940 return true;
941 }
942
943 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
944 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
945 if (type) {
946 // This is a raw type and an already loaded typedef.
947 const char *newname = type->GetFullTypeName();
948 if (type->GetType() == kLong64_t) {
949 newname = "Long64_t";
950 } else if (type->GetType() == kULong64_t) {
951 newname = "ULong64_t";
952 }
953 if (strcmp(inner,newname) == 0) {
954 return true;
955 }
956 if (offset) result = "const ";
957 result += newname;
958 if ( end != tname.length() ) {
959 result += tname.substr(end,tname.length()-end);
960 }
961 if (result == tname) result.clear();
962 return true;
963 }
964
965 // Check if the name is an enumerator
966 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
967 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
968 {
969 // We have a scope
970 // All of this C gymnastic is to avoid allocations on the heap
971 const auto enName = lastPos;
972 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
973 char *scopeName = new char[scopeNameSize + 1];
974 strncpy(scopeName, inner, scopeNameSize);
975 scopeName[scopeNameSize] = '\0';
976 // Check if the scope is in the list of classes
977 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
978 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
979 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
980 }
981 // It may still be in one of the loaded protoclasses
982 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
983 auto listOfEnums = scope->GetListOfEnums();
984 if (listOfEnums) { // it could be null: no enumerators in the protoclass
985 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
986 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
987 }
988 }
989 delete [] scopeName;
990 } else
991 {
992 // We don't have any scope: this could only be a global enum
993 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
994 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
995 }
996
997 if (gCling->GetClassSharedLibs(inner))
998 {
999 // This is a class name.
1000 return true;
1001 }
1002
1003 return false;
1004}
1005
1006////////////////////////////////////////////////////////////////////////////////
1007
1012
1013////////////////////////////////////////////////////////////////////////////////
1014
1016{
1017 return fContent.c_str();
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Append string to the storage if not added already.
1022
1023inline bool TCling::TUniqueString::Append(const std::string& str)
1024{
1025 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1026 if (notPresent){
1027 fContent+=str;
1028 }
1029 return notPresent;
1030}
1031
1032std::string TCling::ToString(const char* type, void* obj)
1033{
1034 return fInterpreter->toString(type, obj);
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038///\returns true if the module was loaded.
1039static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1040{
1041 // When starting up ROOT, cling would load all modulemap files on the include
1042 // paths. However, in a ROOT session, it is very common to run aclic which
1043 // will invoke rootcling and possibly produce a modulemap and a module in
1044 // the current folder.
1045 //
1046 // Before failing, try loading the modulemap in the current folder and try
1047 // loading the requested module from it.
1048 std::string currentDir = gSystem->WorkingDirectory();
1049 assert(!currentDir.empty());
1050 gCling->RegisterPrebuiltModulePath(currentDir);
1051 if (gDebug > 2)
1052 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1053 ModuleName.c_str());
1054
1055 return interp.loadModule(ModuleName, /*Complain=*/true);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Loads the C++ modules that we require to run any ROOT program. This is just
1060/// supposed to make a C++ module from a modulemap available to the interpreter.
1061static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1062{
1063 for (const auto &modName : modules)
1064 LoadModule(modName, interp);
1065}
1066
1067static bool IsFromRootCling() {
1068 // rootcling also uses TCling for generating the dictionary ROOT files.
1069 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1070 return foundSymbol;
1071}
1072
1073/// Checks if there is an ASTFile on disk for the given module \c M.
1074static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1075{
1076 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1077
1078 std::string ModuleFileName;
1079 if (!HSOpts.PrebuiltModulePaths.empty())
1080 // Load the module from *only* in the prebuilt module path.
1081 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1082 if (FullFileName)
1083 *FullFileName = ModuleFileName;
1084
1085 return !ModuleFileName.empty();
1086}
1087
1088static bool HaveFullGlobalModuleIndex = false;
1089static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1090{
1091 CompilerInstance &CI = *interp.getCI();
1092 Preprocessor &PP = CI.getPreprocessor();
1093 auto ModuleManager = CI.getASTReader();
1094 assert(ModuleManager);
1095 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1096 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1097 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1098 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1099 if (ModuleIndexPath.empty())
1100 return nullptr;
1101 // Get an existing global index. This loads it if not already loaded.
1102 ModuleManager->resetForReload();
1103 ModuleManager->loadGlobalIndex();
1104 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1105
1106 // For finding modules needing to be imported for fixit messages,
1107 // we need to make the global index cover all modules, so we do that here.
1108 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1109 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1110 bool RecreateIndex = false;
1111 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1112 Module *TheModule = I->second;
1113 // We want the index only of the prebuilt modules.
1114 if (!HasASTFileOnDisk(TheModule, PP))
1115 continue;
1116 LoadModule(TheModule->Name, interp);
1117 RecreateIndex = true;
1118 }
1119 if (RecreateIndex) {
1120 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1121 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1122
1123 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1124 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1125 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1126 TraverseDecl(TU);
1127 }
1128 bool VisitNamedDecl(NamedDecl *ND) {
1129 if (!ND->isFromASTFile())
1130 return true;
1131 if (!ND->getIdentifier())
1132 return true;
1133
1134 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1135 return true;
1136
1137 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1138 if (TD->isCompleteDefinition())
1139 Register(TD);
1140 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1141 Register(NSD, /*AddSingleEntry=*/ false);
1142 }
1143 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1144 Register(TND);
1145 // FIXME: Add the rest...
1146 return true; // continue decending
1147 }
1148 private:
1149 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1150 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1151 assert(ND->isFromASTFile());
1152 // FIXME: All decls should have an owning module once rootcling
1153 // updates its generated decls from within the LookupHelper & co.
1154 if (!ND->hasOwningModule()) {
1155#ifndef NDEBUG
1156 SourceManager &SM = ND->getASTContext().getSourceManager();
1157 SourceLocation Loc = ND->getLocation();
1158 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1159 (void)FE;
1160 assert(FE->getName().contains("input_line_"));
1161#endif
1162 return;
1163 }
1164
1165 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1166 assert(OwningModule);
1167 assert(!ND->getName().empty() && "Empty name");
1168 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1169 return;
1170 // FIXME: The FileEntry in not stable to serialize.
1171 // FIXME: We might end up with many times with the same module.
1172 // FIXME: We might end up two modules containing a definition.
1173 // FIXME: What do we do if no definition is found.
1174 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1175 }
1176 };
1177 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1178
1179 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1180 CI.getPCHContainerReader(),
1181 ModuleIndexPath,
1182 &IDs));
1183 ModuleManager->resetForReload();
1184 ModuleManager->loadGlobalIndex();
1185 GlobalIndex = ModuleManager->getGlobalIndex();
1186 }
1188 }
1189 return GlobalIndex;
1190}
1191
1192static void RegisterCxxModules(cling::Interpreter &clingInterp)
1193{
1194 if (!clingInterp.getCI()->getLangOpts().Modules)
1195 return;
1196
1197 // Loading of a module might deserialize.
1198 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1199
1200 // Setup core C++ modules if we have any to setup.
1201
1202 // Load libc and stl first.
1203 // Load vcruntime module for windows
1204#ifdef R__WIN32
1205 LoadModule("vcruntime", clingInterp);
1206 LoadModule("services", clingInterp);
1207#endif
1208
1209#ifdef R__MACOSX
1210 LoadModule("Darwin", clingInterp);
1211#else
1212 LoadModule("libc", clingInterp);
1213#endif
1214 LoadModule("std", clingInterp);
1215
1216 LoadModule("_Builtin_intrinsics", clingInterp);
1217
1218 // Load core modules
1219 // This should be vector in order to be able to pass it to LoadModules
1220 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1221 "ROOT_Config",
1222 "ROOT_Rtypes",
1223 "ROOT_Foundation_Stage1_NoRTTI",
1224 "Core",
1225 "Rint",
1226 "RIO"};
1227
1228 LoadModules(CoreModules, clingInterp);
1229
1230 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1231 if (!IsFromRootCling()) {
1232 std::vector<std::string> CommonModules = {"MathCore"};
1233 LoadModules(CommonModules, clingInterp);
1234
1235 // These modules should not be preloaded but they fix issues.
1236 // FIXME: Hist is not a core module but is very entangled to MathCore and
1237 // causes issues.
1238 std::vector<std::string> FIXMEModules = {"Hist"};
1239 clang::CompilerInstance &CI = *clingInterp.getCI();
1240 clang::Preprocessor &PP = CI.getPreprocessor();
1241 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1242 if (MMap.findModule("RInterface"))
1243 FIXMEModules.push_back("RInterface");
1244
1245 LoadModules(FIXMEModules, clingInterp);
1246
1247 GlobalModuleIndex *GlobalIndex = nullptr;
1248 loadGlobalModuleIndex(clingInterp);
1249 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1250 // We should investigate how to suppress it completely.
1251 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1252
1253 llvm::StringSet<> KnownModuleFileNames;
1254 if (GlobalIndex)
1255 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1256
1257 std::vector<std::string> PendingModules;
1258 PendingModules.reserve(256);
1259 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1260 clang::Module *M = I->second;
1261 assert(M);
1262
1263 // We want to load only already created modules.
1264 std::string FullASTFilePath;
1265 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1266 continue;
1267
1268 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1269 continue;
1270
1271 if (M->IsUnimportable)
1272 continue;
1273
1274 if (GlobalIndex)
1275 LoadModule(M->Name, clingInterp);
1276 else {
1277 // FIXME: We may be able to remove those checks as cling::loadModule
1278 // checks if a module was alredy loaded.
1279 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1280 continue; // This is a core module which was already loaded.
1281
1282 // Load system modules now and delay the other modules after we have
1283 // loaded all system ones.
1284 if (M->IsSystem)
1285 LoadModule(M->Name, clingInterp);
1286 else
1287 PendingModules.push_back(M->Name);
1288 }
1289 }
1290 LoadModules(PendingModules, clingInterp);
1291 }
1292
1293 // Check that the gROOT macro was exported by any core module.
1294 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1295
1296 // `ERROR` and `PI` are from loading R related modules, which conflict with
1297 // user's code.
1298 clingInterp.declare(R"CODE(
1299#ifdef PI
1300# undef PI
1301#endif
1302#ifdef ERROR
1303# undef ERROR
1304#endif
1305 )CODE");
1306}
1307
1308static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1309{
1310 std::string PreIncludes;
1311 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1312
1313 // For the list to also include string, we have to include it now.
1314 // rootcling does parts already if needed, e.g. genreflex does not want using
1315 // namespace std.
1316 if (IsFromRootCling()) {
1317 PreIncludes += "#include \"RtypesCore.h\"\n";
1318 } else {
1319 if (!hasCxxModules)
1320 PreIncludes += "#include \"Rtypes.h\"\n";
1321
1322 PreIncludes += gClassDefInterpMacro + "\n"
1323 + gInterpreterClassDef + "\n"
1324 "#undef ClassImp\n"
1325 "#define ClassImp(X);\n";
1326 }
1327 if (!hasCxxModules)
1328 PreIncludes += "#include <string>\n";
1329
1330 // We must include it even when we have modules because it is marked as
1331 // textual in the modulemap due to the nature of the assert header.
1332#ifndef R__WIN32
1333 PreIncludes += "#include <cassert>\n";
1334#endif
1335 PreIncludes += "using namespace std;\n";
1336 clingInterp.declare(PreIncludes);
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Initialize the cling interpreter interface.
1341/// \param name name for TInterpreter
1342/// \param title title for TInterpreter
1343/// \param argv - array of arguments passed to the cling::Interpreter constructor
1344/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1345
1346TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1347: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1349 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1351{
1352 fPrompt[0] = 0;
1353 const bool fromRootCling = IsFromRootCling();
1354
1355 fCxxModulesEnabled = false;
1356#ifdef R__USE_CXXMODULES
1357 fCxxModulesEnabled = true;
1358#endif
1359
1360 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1361
1362 fTemporaries = new std::vector<cling::Value>();
1363
1364 std::vector<std::string> clingArgsStorage;
1365 clingArgsStorage.push_back("cling4root");
1366 for (const char* const* arg = argv; *arg; ++arg)
1367 clingArgsStorage.push_back(*arg);
1368
1369 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1370 if (!fromRootCling) {
1372
1373 // Add -I early so ASTReader can find the headers.
1374 std::string interpInclude(TROOT::GetEtcDir().Data());
1375 clingArgsStorage.push_back("-I" + interpInclude);
1376
1377 // Add include path to etc/cling.
1378 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1379
1380 // Add include path to etc/cling.
1381 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1382
1383 // Add the root include directory and etc/ to list searched by default.
1384 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1385
1386 // Add the current path to the include path
1387 // TCling::AddIncludePath(".");
1388
1389 // Attach the PCH (unless we have C++ modules enabled which provide the
1390 // same functionality).
1391 if (!fCxxModulesEnabled) {
1392 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1393 if (gSystem->Getenv("ROOT_PCH")) {
1394 pchFilename = gSystem->Getenv("ROOT_PCH");
1395 }
1396
1397 clingArgsStorage.push_back("-include-pch");
1398 clingArgsStorage.push_back(pchFilename);
1399 }
1400
1401 clingArgsStorage.push_back("-Wno-undefined-inline");
1402 clingArgsStorage.push_back("-fsigned-char");
1403 clingArgsStorage.push_back("-fsized-deallocation");
1404 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1405 // See the GitHub issues #9809 and #9944
1406 // TODO: to be reviewed after the upgrade of LLVM & Clang
1407#ifndef _MSC_VER
1408 clingArgsStorage.push_back("-O1");
1409 // Disable optimized register allocation which is turned on automatically
1410 // by -O1, but seems to require -O2 to not explode in run time.
1411 clingArgsStorage.push_back("-mllvm");
1412 clingArgsStorage.push_back("-optimize-regalloc=0");
1413#endif
1414 }
1415
1416 // Process externally passed arguments if present.
1417 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1418 if (EnvOpt.has_value()) {
1419 StringRef Env(*EnvOpt);
1420 while (!Env.empty()) {
1421 StringRef Arg;
1422 std::tie(Arg, Env) = Env.split(' ');
1423 clingArgsStorage.push_back(Arg.str());
1424 }
1425 }
1426
1427 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1428 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1429 if (EnvOpt.has_value()) {
1430 StringRef Env(*EnvOpt);
1431 while (!Env.empty()) {
1432 StringRef Arg;
1433 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1434 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1435 Paths.push_back(Arg.str());
1436 }
1437 }
1438 };
1439
1440 if (fCxxModulesEnabled) {
1441 std::vector<std::string> Paths;
1442 // ROOT usually knows better where its libraries are. This way we can
1443 // discover modules without having to should thisroot.sh and should fix
1444 // gnuinstall.
1445 Paths.push_back(TROOT::GetSharedLibDir().Data());
1446 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1447 std::string EnvVarPath;
1448 for (const std::string& P : Paths)
1450 // FIXME: We should make cling -fprebuilt-module-path work.
1451 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1452 }
1453
1454 // FIXME: This only will enable frontend timing reports.
1455 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1456 if (EnvOpt.has_value())
1457 clingArgsStorage.push_back("-ftime-report");
1458
1459 // Add the overlay file. Note that we cannot factor it out for both root
1460 // and rootcling because rootcling activates modules only if -cxxmodule
1461 // flag is passed.
1462 if (fCxxModulesEnabled && !fromRootCling) {
1463 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1464 std::vector<std::string> ModuleMaps;
1465 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1466 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1467 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1468
1469 std::string cwd = gSystem->WorkingDirectory();
1470 // Give highest precedence of the modulemap in the cwd if any.
1471 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1472 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1473
1474 for (const std::string& M : ModuleMaps)
1475 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1476
1477 std::string ModulesCachePath;
1478 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1479 if (EnvOpt.has_value()){
1480 StringRef Env(*EnvOpt);
1481 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1482 ModulesCachePath = Env.str();
1483 } else {
1484 ModulesCachePath = TROOT::GetSharedLibDir();
1485 }
1486
1487 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1488 }
1489
1490 std::vector<const char*> interpArgs;
1491 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1492 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1493 interpArgs.push_back(iArg->c_str());
1494
1495 // Activate C++ modules support. If we are running within rootcling, it's up
1496 // to rootcling to set this flag depending on whether it wants to produce
1497 // C++ modules.
1498 TString vfsArg;
1499 if (fCxxModulesEnabled) {
1500 if (!fromRootCling) {
1501 // We only set this flag, rest is done by the CIFactory.
1502 interpArgs.push_back("-fmodules");
1503 interpArgs.push_back("-fno-implicit-module-maps");
1504 // We should never build modules during runtime, so let's enable the
1505 // module build remarks from clang to make it easier to spot when we do
1506 // this by accident.
1507 interpArgs.push_back("-Rmodule-build");
1508 }
1509 // ROOT implements its AutoLoading upon module's link directives. We
1510 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1511 // facilities use the link directive to dynamically load the relevant
1512 // library. So, we need to suppress clang's default autolink behavior.
1513 interpArgs.push_back("-fno-autolink");
1514 }
1515
1516#ifdef R__FAST_MATH
1517 // Same setting as in rootcling_impl.cxx.
1518 interpArgs.push_back("-ffast-math");
1519#endif
1520
1521 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1522 // Add statically injected extra arguments, usually coming from rootcling.
1523 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1524 extraArgs && *extraArgs; ++extraArgs) {
1525 if (!strcmp(*extraArgs, "-resource-dir")) {
1526 // Take the next arg as the llvm resource directory.
1527 llvmResourceDir = *(++extraArgs);
1528 } else {
1529 interpArgs.push_back(*extraArgs);
1530 }
1531 }
1532
1533 std::vector<std::string> _empty;
1534 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1535 for (const auto &arg: args)
1536 interpArgs.emplace_back(arg.c_str());
1537
1538 // Add the Rdict module file extension.
1539 cling::Interpreter::ModuleFileExtensions extensions;
1540 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1541 if (!EnvOpt.has_value())
1542 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1543
1544 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1545 &(interpArgs[0]),
1546 llvmResourceDir, extensions,
1547 interpLibHandle);
1548
1549 // Don't check whether modules' files exist.
1550 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1551 DisableValidationForModuleKind::All;
1552
1553 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1554 // to disable spell checking.
1555 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1556
1557 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1558 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1559 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1560 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1561
1562 // We need stream that doesn't close its file descriptor, thus we are not
1563 // using llvm::outs. Keeping file descriptor open we will be able to use
1564 // the results in pipes (Savannah #99234).
1565 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1566 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1567
1570
1571 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1578
1579 // Disallow auto-parsing in rootcling
1580 fIsAutoParsingSuspended = fromRootCling;
1581
1582 ResetAll();
1583
1584 // Enable dynamic lookup
1585 if (!fromRootCling) {
1586 fInterpreter->enableDynamicLookup();
1587 }
1588
1589 // Enable ClinG's DefinitionShadower for ROOT.
1590 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1591 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1592 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1593 // FIXME: We should probably switch to the default printing policy setting
1594 // after adjusting tons of reference files.
1595 Policy.SplitTemplateClosers = true;
1596 // Keep default templare arguments, required for dictionary generation.
1597 Policy.SuppressDefaultTemplateArgs = false;
1598
1599
1600 // Attach cling callbacks last; they might need TROOT::fInterpreter
1601 // and should thus not be triggered during the equivalent of
1602 // TROOT::fInterpreter = new TCling;
1603 std::unique_ptr<TClingCallbacks>
1604 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1605 fClingCallbacks = clingCallbacks.get();
1606 fClingCallbacks->SetAutoParsingSuspended(fIsAutoParsingSuspended);
1607 fInterpreter->setCallbacks(std::move(clingCallbacks));
1608
1609 if (!fromRootCling) {
1610 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1611 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1612 // e.g. because of an RPATH build.
1613 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1614 /*prepend=*/true);
1615 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1616 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1617 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1618 };
1619 // Initialize the dyld for AutoloadLibraryGenerator.
1620 DLM.initializeDyld(ShouldPermanentlyIgnore);
1621 }
1622}
1623
1624
1625////////////////////////////////////////////////////////////////////////////////
1626/// Destroy the interpreter interface.
1627
1629{
1630 // ROOT's atexit functions require the interepreter to be available.
1631 // Run them before shutting down.
1632 if (!IsFromRootCling())
1633 GetInterpreterImpl()->runAtExitFuncs();
1634 fIsShuttingDown = true;
1635 delete fMapfile;
1636 delete fRootmapFiles;
1637 delete fTemporaries;
1638 delete fNormalizedCtxt;
1639 delete fLookupHelper;
1640 gCling = nullptr;
1641}
1642
1643////////////////////////////////////////////////////////////////////////////////
1644/// Initialize the interpreter, once TROOT::fInterpreter is set.
1645
1647{
1648 fClingCallbacks->Initialize();
1649
1650 // We are set up. Enable ROOT's AutoLoading.
1651 if (IsFromRootCling())
1652 return;
1653
1654 // Read the rules before enabling the auto loading to not inadvertently
1655 // load the libraries for the classes concerned even-though the user is
1656 // *not* using them.
1657 // Note this call must happen before the first call to LoadLibraryMap.
1658 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1659 TClass::ReadRules(); // Read the default customization rules ...
1660
1662 SetClassAutoLoading(true);
1663}
1664
1666{
1667 fIsShuttingDown = true;
1668 ResetGlobals();
1669}
1670
1671////////////////////////////////////////////////////////////////////////////////
1672/// Helper to initialize TVirtualStreamerInfo's factor early.
1673/// Use static initialization to insure only one TStreamerInfo is created.
1675{
1676 // Use lambda since SetFactory return void.
1677 auto setFactory = []() {
1679 return kTRUE;
1680 };
1681 static bool doneFactory = setFactory();
1682 return doneFactory; // avoid unused variable warning.
1683}
1684
1685////////////////////////////////////////////////////////////////////////////////
1686/// Register Rdict data for future loading by LoadPCM;
1687
1688void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1689{
1690 if (IsFromRootCling())
1691 return;
1692
1693 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1694 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1695 return;
1696 }
1697
1698 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1699 // a link to a non-existent file.
1700 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1701}
1702
1703////////////////////////////////////////////////////////////////////////////////
1704/// Tries to load a PCM from TFile; returns true on success.
1705/// The caller of this function should be holding the ROOT Write lock.
1706
1708{
1709 auto listOfKeys = pcmFile.GetListOfKeys();
1710
1711 // This is an empty pcm
1712 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1713 ((listOfKeys->GetSize() == 1) && // only one, and
1714 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1715 ))) {
1716 return;
1717 }
1718
1719 TObjArray *protoClasses;
1720 if (gDebug > 1)
1721 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1722
1723 TObjArray *enums;
1724 pcmFile.GetObject("__Enums", enums);
1725 if (enums) {
1726 // Cache the pointers
1727 auto listOfGlobals = gROOT->GetListOfGlobals();
1728 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1729 // Loop on enums and then on enum constants
1730 for (auto selEnum : *enums) {
1731 const char *enumScope = selEnum->GetTitle();
1732 const char *enumName = selEnum->GetName();
1733 if (strcmp(enumScope, "") == 0) {
1734 // This is a global enum and is added to the
1735 // list of enums and its constants to the list of globals
1736 if (!listOfEnums->THashList::FindObject(enumName)) {
1737 ((TEnum *)selEnum)->SetClass(nullptr);
1738 listOfEnums->Add(selEnum);
1739 }
1740 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1741 if (!listOfGlobals->FindObject(enumConstant)) {
1742 listOfGlobals->Add(enumConstant);
1743 }
1744 }
1745 } else {
1746 // This enum is in a namespace. A TClass entry is bootstrapped if
1747 // none exists yet and the enum is added to it
1748 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1749 if (!nsTClassEntry) {
1750 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1751 }
1752 auto listOfEnums = nsTClassEntry->fEnums.load();
1753 if (!listOfEnums) {
1754 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1755 // For this case, the list will be immutable once constructed
1756 // (i.e. in this case, by the end of this routine).
1757 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1758 } else {
1759 // namespaces can have enums added to them
1760 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1761 }
1762 }
1763 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1764 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1765 listOfEnums->Add(selEnum);
1766 }
1767 }
1768 }
1769 enums->Clear();
1770 delete enums;
1771 }
1772
1773 pcmFile.GetObject("__ProtoClasses", protoClasses);
1774
1775 if (protoClasses) {
1776 for (auto obj : *protoClasses) {
1777 TProtoClass *proto = (TProtoClass *)obj;
1779 }
1780 // Now that all TClass-es know how to set them up we can update
1781 // existing TClasses, which might cause the creation of e.g. TBaseClass
1782 // objects which in turn requires the creation of TClasses, that could
1783 // come from the PCH, but maybe later in the loop. Instead of resolving
1784 // a dependency graph the addition to the TClassTable above allows us
1785 // to create these dependent TClasses as needed below.
1786 for (auto proto : *protoClasses) {
1787 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1788 // We have an existing TClass object. It might be emulated
1789 // or interpreted; we now have more information available.
1790 // Make that available.
1791 if (existingCl->GetState() != TClass::kHasTClassInit) {
1792 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1793 if (!dict) {
1794 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1795 } else {
1796 // This will replace the existing TClass.
1797 TClass *ncl = (*dict)();
1798 if (ncl)
1799 ncl->PostLoadCheck();
1800 }
1801 }
1802 }
1803 }
1804
1805 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1806 delete protoClasses;
1807 }
1808
1809 TObjArray *dataTypes;
1810 pcmFile.GetObject("__Typedefs", dataTypes);
1811 if (dataTypes) {
1812 for (auto typedf : *dataTypes)
1813 gROOT->GetListOfTypes()->Add(typedf);
1814 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1815 delete dataTypes;
1816 }
1817}
1818
1819////////////////////////////////////////////////////////////////////////////////
1820/// Tries to load a rdict PCM, issues diagnostics if it fails.
1821/// The caller of this function should be holding the ROOT Write lock.
1822
1823void TCling::LoadPCM(std::string pcmFileNameFullPath)
1824{
1825 SuspendAutoLoadingRAII autoloadOff(this);
1826 SuspendAutoParsing autoparseOff(this);
1827 assert(!pcmFileNameFullPath.empty());
1828 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1829
1830 // Easier to work with the ROOT interfaces.
1831 TString pcmFileName = pcmFileNameFullPath;
1832
1833 // Prevent the ROOT-PCMs hitting this during auto-load during
1834 // JITting - which will cause recursive compilation.
1835 // Avoid to call the plugin manager at all.
1837
1839 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1840 if (gDebug > 5) {
1841 gDebug -= 5;
1842 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1843 } else {
1844 gDebug = 0;
1845 }
1846
1847 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1848 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1849
1850 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1851 if (pendingRdict != fPendingRdicts.end()) {
1852 llvm::StringRef pcmContent = pendingRdict->second;
1853 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1854 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1855 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1856
1857 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1858 LoadPCMImpl(pcmMemFile);
1859 // Currently the module file are never unloaded (even if the library is
1860 // unloaded) and, of course, never reloaded.
1861 // Consequently, we must NOT remove the `pendingRdict` from the list
1862 // of pending dictionary, otherwise if a library is unloaded and then
1863 // reload we will be unable to update properly the TClass object
1864 // (because we wont be able to load the rootpcm file by executing the
1865 // above lines)
1866
1867 return;
1868 }
1869
1870 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1871 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1872 pcmFileNameFullPath.data());
1873 if (!fPendingRdicts.empty())
1874 for (const auto &rdict : fPendingRdicts)
1875 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1876 rdict.first.c_str());
1877 return;
1878 }
1879
1880 if (!gROOT->IsRootFile(pcmFileName)) {
1881 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1882 return;
1883 }
1884 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1885 LoadPCMImpl(pcmFile);
1886}
1887
1888//______________________________________________________________________________
1889
1890namespace {
1891 using namespace clang;
1892
1893 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1894 // This class is to be considered an helper for autoparsing.
1895 // It visits the AST and marks all classes (in all of their redeclarations)
1896 // with the setHasExternalLexicalStorage method.
1897 public:
1898 bool VisitRecordDecl(clang::RecordDecl* rcd){
1899 if (gDebug > 2)
1900 Info("ExtLexicalStorageAdder",
1901 "Adding external lexical storage to class %s",
1902 rcd->getNameAsString().c_str());
1903 auto reDeclPtr = rcd->getMostRecentDecl();
1904 do {
1905 reDeclPtr->setHasExternalLexicalStorage();
1906 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1907
1908 return false;
1909 }
1910 };
1911
1912
1913}
1914
1915////////////////////////////////////////////////////////////////////////////////
1916///\returns true if the module map was loaded, false on error or if the map was
1917/// already loaded.
1918bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1919 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1920{
1921 assert(llvm::sys::path::is_absolute(FullPath));
1922 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1923 FileManager &FM = PP.getFileManager();
1924 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1925 // We should look for modulemap files there too.
1926 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1927 HeaderSearch &HS = PP.getHeaderSearchInfo();
1928 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1929 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1930 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1931 if (!pathExists)
1932 HSOpts.AddPrebuiltModulePath(FullPath);
1933 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1934 // because its internal call to getFile has CacheFailure set to true.
1935 // In our case, modulemaps can appear any time due to ACLiC.
1936 // Code copied from HS.lookupModuleMapFile.
1937 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1938 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1939 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1940 /*CacheFailure*/ false)) {
1941 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1942 return true;
1943 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1944 }
1945 }
1946 return false;
1947}
1948
1949////////////////////////////////////////////////////////////////////////////////
1950/// List of dicts that have the PCM information already in the PCH.
1951static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1952 "libRint",
1953 "libThread",
1954 "libRIO",
1955 "libImt",
1956 "libMultiProc",
1957 "libcomplexDict",
1958 "libdequeDict",
1959 "liblistDict",
1960 "libforward_listDict",
1961 "libvectorDict",
1962 "libmapDict",
1963 "libmultimap2Dict",
1964 "libmap2Dict",
1965 "libmultimapDict",
1966 "libsetDict",
1967 "libmultisetDict",
1968 "libunordered_setDict",
1969 "libunordered_multisetDict",
1970 "libunordered_mapDict",
1971 "libunordered_multimapDict",
1972 "libvalarrayDict",
1973 "G__GenVector32",
1974 "G__Smatrix32"};
1975
1976static void PrintDlError(const char *dyLibName, const char *modulename)
1977{
1978#ifdef R__WIN32
1979 char dyLibError[1000];
1980 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1981 dyLibError, sizeof(dyLibError), NULL);
1982#else
1983 const char *dyLibError = dlerror();
1984#endif
1985 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1986 (dyLibError) ? dyLibError : "");
1987}
1988
1989////////////////////////////////////////////////////////////////////////////////
1990// Update all the TClass registered in fClassesToUpdate
1991
1993{
1994 while (!fClassesToUpdate.empty()) {
1995 TClass *oldcl = fClassesToUpdate.back().first;
1996 // If somehow the TClass has already been loaded (maybe it was registered several time),
1997 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1998 // maybe even kForwardDeclared and needs to replaced.
1999 if (oldcl->GetState() != TClass::kHasTClassInit) {
2000 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2001 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2002 fClassesToUpdate.pop_back();
2003 // Calling func could manipulate the list so, let maintain the list
2004 // then call the dictionary function.
2005 TClass *ncl = dict();
2006 if (ncl) ncl->PostLoadCheck();
2007 } else {
2008 fClassesToUpdate.pop_back();
2009 }
2010 }
2011}
2012////////////////////////////////////////////////////////////////////////////////
2013/// Inject the module named "modulename" into cling; load all headers.
2014/// headers is a 0-terminated array of header files to `#include` after
2015/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2016/// entries (or %PATH% on Windows).
2017/// This function gets called by the static initialization of dictionary
2018/// libraries.
2019/// The payload code is injected "as is" in the interpreter.
2020/// The value of 'triggerFunc' is used to find the shared library location.
2021/// The caller of this function should be holding the ROOT Write lock.
2022
2023void TCling::RegisterModule(const char* modulename,
2024 const char** headers,
2025 const char** includePaths,
2026 const char* payloadCode,
2027 const char* fwdDeclsCode,
2028 void (*triggerFunc)(),
2029 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2030 const char** classesHeaders,
2031 Bool_t lateRegistration /*=false*/,
2032 Bool_t hasCxxModule /*=false*/)
2033{
2034 const bool fromRootCling = IsFromRootCling();
2035 // We need the dictionary initialization but we don't want to inject the
2036 // declarations into the interpreter, except for those we really need for
2037 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2038 if (fromRootCling) return;
2039
2040 // When we cannot provide a module for the library we should enable header
2041 // parsing. This 'mixed' mode ensures gradual migration to modules.
2042 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2043 fHeaderParsingOnDemand = !hasCxxModule;
2044
2045 // Treat Aclic Libs in a special way. Do not delay the parsing.
2046 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2047 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2048 if (hasHeaderParsingOnDemand && isACLiC) {
2049 if (gDebug>1)
2050 Info("TCling::RegisterModule",
2051 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2052 hasHeaderParsingOnDemand = false;
2053 }
2054
2055
2056 // Make sure we relookup symbols that were search for before we loaded
2057 // their autoparse information. We could be more subtil and remove only
2058 // the failed one or only the one in this module, but for now this is
2059 // better than nothing.
2060 fLookedUpClasses.clear();
2061
2062 // Make sure we do not set off AutoLoading or autoparsing during the
2063 // module registration!
2064 SuspendAutoLoadingRAII autoLoadOff(this);
2065
2066 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2067 TCling::AddIncludePath(*inclPath);
2068 }
2069 cling::Transaction* T = nullptr;
2070 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2071 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2072 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2073 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2074 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2075 assert(cling::Interpreter::kSuccess == compRes &&
2076 "A fwd declaration could not be compiled");
2077 if (compRes!=cling::Interpreter::kSuccess){
2078 Warning("TCling::RegisterModule",
2079 "Problems in declaring string '%s' were encountered.",
2080 fwdDecl.c_str()) ;
2081 continue;
2082 }
2083
2084 // Drill through namespaces recursively until the template is found
2085 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2086 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2087 }
2088
2089 }
2090
2091 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2092 // This is used to give Sema the same view on ACLiC'ed files (which
2093 // are then #included through the dictionary) as rootcling had.
2094 TString code = gNonInterpreterClassDef;
2095 if (payloadCode)
2096 code += payloadCode;
2097
2098 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2099 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2100
2101 if (dyLibName.empty()) {
2102 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2103 return;
2104 }
2105
2106 // The triggerFunc may not be in a shared object but in an executable.
2107 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2108
2109 bool wasDlopened = false;
2110
2111 // If this call happens after dlopen has finished (i.e. late registration)
2112 // there is no need to dlopen the library recursively. See ROOT-8437 where
2113 // the dyLibName would correspond to the binary.
2114 if (!lateRegistration) {
2115
2116 if (isSharedLib) {
2117 // We need to open the dictionary shared library, to resolve symbols
2118 // requested by the JIT from it: as the library is currently being dlopen'ed,
2119 // its symbols are not yet reachable from the process.
2120 // Recursive dlopen seems to work just fine.
2121 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2122 if (dyLibHandle) {
2123 fRegisterModuleDyLibs.push_back(dyLibHandle);
2124 wasDlopened = true;
2125 } else {
2126 PrintDlError(dyLibName.c_str(), modulename);
2127 }
2128 }
2129 } // if (!lateRegistration)
2130
2131 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2132 // We now parse the forward declarations. All the classes are then modified
2133 // in order for them to have an external lexical storage.
2134 std::string fwdDeclsCodeLessEnums;
2135 {
2136 // Search for enum forward decls and only declare them if no
2137 // declaration exists yet.
2138 std::string fwdDeclsLine;
2139 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2140 std::vector<std::string> scopes;
2141 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2142 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2143 // We check if the line contains a fwd declaration of an enum
2144 if (enumPos != std::string::npos) {
2145 // We clear the scopes which we may have carried from a previous iteration
2146 scopes.clear();
2147 // We check if the enum is not in a scope. If yes, save its name
2148 // and the names of the enclosing scopes.
2149 if (enumPos != 0) {
2150 // it's enclosed in namespaces. We need to understand what they are
2151 auto nsPos = fwdDeclsLine.find("namespace");
2152 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2153 while (nsPos < enumPos && nsPos != std::string::npos) {
2154 // we have a namespace, let's put it in the collection of scopes
2155 const auto nsNameStart = nsPos + 10;
2156 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2157 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2158 scopes.push_back(nsName);
2159 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2160 }
2161 }
2162 clang::DeclContext* DC = nullptr;
2163 for (auto &&aScope: scopes) {
2164 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2165 if (!DC) {
2166 // No decl context means we have to fwd declare the enum.
2167 break;
2168 }
2169 }
2170 if (scopes.empty() || DC) {
2171 // We know the scope; let's look for the enum. For that, look
2172 // for the *last* closing parentheses of an attribute because
2173 // there can be multiple.
2174 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2175 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2176 posEnumName += 5; // skip "\"))) "
2177 while (isspace(fwdDeclsLine[posEnumName]))
2178 ++posEnumName;
2179 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2180 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2181 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2182 --posEnumNameEnd;
2183 // posEnumNameEnd now points to the last character of the name.
2184
2185 std::string enumName = fwdDeclsLine.substr(posEnumName,
2186 posEnumNameEnd - posEnumName + 1);
2187
2188 if (clang::NamedDecl* enumDecl
2189 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2190 enumName.c_str(), DC)) {
2191 // We have an existing enum decl (forward or definition);
2192 // skip this.
2193 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2194 (void)enumDecl;
2195 continue;
2196 }
2197 }
2198 }
2199
2200 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2201 }
2202 }
2203
2204 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2205 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2206 assert(cling::Interpreter::kSuccess == compRes &&
2207 "The forward declarations could not be compiled");
2208 if (compRes!=cling::Interpreter::kSuccess){
2209 Warning("TCling::RegisterModule",
2210 "Problems in compiling forward declarations for module %s: '%s'",
2211 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2212 }
2213 else if (T){
2214 // Loop over all decls in the transaction and go through them all
2215 // to mark them properly.
2216 // In order to do that, we first iterate over all the DelayedCallInfos
2217 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2218 // contained in the DelayedCallInfos. For each decl, we traverse.
2219 ExtLexicalStorageAdder elsa;
2220 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2221 cling::Transaction::DelayCallInfo& dci = *dciIt;
2222 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2223 clang::Decl* declPtr = *dit;
2224 elsa.TraverseDecl(declPtr);
2225 }
2226 }
2227 }
2228 }
2229
2230 // Now we register all the headers necessary for the class
2231 // Typical format of the array:
2232 // {"A", "classes.h", "@",
2233 // "vector<A>", "vector", "@",
2234 // "myClass", payloadCode, "@",
2235 // nullptr};
2236
2237 std::string temp;
2238 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2239 temp=*classesHeader;
2240
2241 size_t theTemplateHash = 0;
2242 bool addTemplate = false;
2243 size_t posTemplate = temp.find('<');
2244 if (posTemplate != std::string::npos) {
2245 // Add an entry for the template itself.
2246 std::string templateName = temp.substr(0, posTemplate);
2247 theTemplateHash = fStringHashFunction(templateName);
2248 addTemplate = true;
2249 }
2250 size_t theHash = fStringHashFunction(temp);
2251 classesHeader++;
2252 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2253 // This is done in order to distinguish headers from files and from the payloadCode
2254 if (payloadCode == *classesHeader_inner ){
2255 fPayloads.insert(theHash);
2256 if (addTemplate) fPayloads.insert(theTemplateHash);
2257 }
2258 if (gDebug > 2)
2259 Info("TCling::RegisterModule",
2260 "Adding a header for %s", temp.c_str());
2261 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2262 if (addTemplate) {
2263 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2264 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2265 }
2266 addTemplate = false;
2267 }
2268 }
2269 }
2270 }
2271
2272 clang::Sema &TheSema = fInterpreter->getSema();
2273
2274 bool ModuleWasSuccessfullyLoaded = false;
2275 if (hasCxxModule) {
2276 std::string ModuleName = modulename;
2277 if (llvm::StringRef(modulename).startswith("lib"))
2278 ModuleName = llvm::StringRef(modulename).substr(3).str();
2279
2280 // In case we are directly loading the library via gSystem->Load() without
2281 // specifying the relevant include paths we should try loading the
2282 // modulemap next to the library location.
2283 clang::Preprocessor &PP = TheSema.getPreprocessor();
2284 std::string ModuleMapName;
2285 if (isACLiC)
2286 ModuleMapName = ModuleName + ".modulemap";
2287 else
2288 ModuleMapName = "module.modulemap";
2289 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2290 ModuleMapName);
2291
2292 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2293 // modules such as GenVector32 because it needs to fall back to GenVector.
2294 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2295 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2296 if (!ModuleWasSuccessfullyLoaded) {
2297 // Only report if we found the module in the modulemap.
2298 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2299 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2300 if (moduleMap.findModule(ModuleName))
2301 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2302 }
2303 }
2304
2305 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2306 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2307 // The path dyLibName might not be absolute. This can happen if dyLibName
2308 // is linked to an executable in the same folder.
2309 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2310 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2311 llvm::sys::path::append(pcmFileNameFullPath,
2313 LoadPCM(pcmFileNameFullPath.str().str());
2314 }
2315
2316 { // scope within which diagnostics are de-activated
2317 // For now we disable diagnostics because we saw them already at
2318 // dictionary generation time. That won't be an issue with the PCMs.
2319
2320 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2321
2322#if defined(R__MUST_REVISIT)
2323#if R__MUST_REVISIT(6,2)
2324 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2325#endif
2326#endif
2327
2328 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2329 SuspendAutoParsing autoParseRaii(this);
2330
2331 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2332 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2333 if (isACLiC) {
2334 // Register an unload point.
2335 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2336 }
2337
2338 assert(cling::Interpreter::kSuccess == compRes &&
2339 "Payload code of a dictionary could not be parsed correctly.");
2340 if (compRes!=cling::Interpreter::kSuccess) {
2341 Warning("TCling::RegisterModule",
2342 "Problems declaring payload for module %s.", modulename) ;
2343 }
2344 }
2345 }
2346
2347 // Now that all the header have been registered/compiled, let's
2348 // make sure to 'reset' the TClass that have a class init in this module
2349 // but already had their type information available (using information/header
2350 // loaded from other modules or from class rules or from opening a TFile
2351 // or from loading header in a way that did not provoke the loading of
2352 // the library we just loaded).
2354
2355 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2356 // __ROOTCLING__ might be pulled in through PCH
2357 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2358 "#undef __ROOTCLING__\n"
2359 + gInterpreterClassDef +
2360 "#endif");
2361 }
2362
2363 if (wasDlopened) {
2364 assert(isSharedLib);
2365 void* dyLibHandle = fRegisterModuleDyLibs.back();
2366 fRegisterModuleDyLibs.pop_back();
2367 dlclose(dyLibHandle);
2368 }
2369}
2370
2372 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2373 ASTContext &C = CI.getASTContext();
2374
2375 // Do not do anything if we have no global module index.
2376 // FIXME: This is mostly to real with false positives in the TTabCom
2377 // interface for non-modules.
2378 if (!fCxxModulesEnabled)
2379 return;
2380
2381 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2382 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2383 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2384 std::string I = Ident.str();
2385 if (!Idents.Contains(I.data()))
2386 Idents.Add(new TObjString(I.c_str()));
2387 }
2388 }
2389}
2390
2391
2392////////////////////////////////////////////////////////////////////////////////
2393/// Register classes that already existed prior to their dictionary loading
2394/// and that already had a ClassInfo (and thus would not be refresh via
2395/// UpdateClassInfo.
2396
2398{
2399 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2400}
2401
2402////////////////////////////////////////////////////////////////////////////////
2403/// If the dictionary is loaded, we can remove the class from the list
2404/// (otherwise the class might be loaded twice).
2405
2407{
2408 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2409 iterator stop = fClassesToUpdate.end();
2410 for(iterator i = fClassesToUpdate.begin();
2411 i != stop;
2412 ++i)
2413 {
2414 if ( i->first == oldcl ) {
2415 fClassesToUpdate.erase(i);
2416 return;
2417 }
2418 }
2419}
2420
2421
2422////////////////////////////////////////////////////////////////////////////////
2423/// Let cling process a command line.
2424///
2425/// If the command is executed and the error is 0, then the return value
2426/// is the int value corresponding to the result of the executed command
2427/// (float and double return values will be truncated).
2428///
2429
2430// Method for handling the interpreter exceptions.
2431// the MetaProcessor is passing in as argument to teh function, because
2432// cling::Interpreter::CompilationResult is a nested class and it cannot be
2433// forward declared, thus this method cannot be a static member function
2434// of TCling.
2435
2436static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2437 const char* input_line,
2438 cling::Interpreter::CompilationResult& compRes,
2439 cling::Value* result)
2440{
2441 try {
2442 return metaProcessor->process(input_line, compRes, result);
2443 }
2444 catch (cling::InterpreterException& ex)
2445 {
2446 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2447 ex.diagnose();
2448 compRes = cling::Interpreter::kFailure;
2449 }
2450 return 0;
2451}
2452
2453////////////////////////////////////////////////////////////////////////////////
2454
2455bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2456{
2457 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2458 ie->diagnose();
2459 return true;
2460 }
2461 return false;
2462}
2463
2464////////////////////////////////////////////////////////////////////////////////
2465
2467{
2468 // Copy the passed line, it comes from a static buffer in TApplication
2469 // which can be reentered through the Cling evaluation routines,
2470 // which would overwrite the static buffer and we would forget what we
2471 // were doing.
2472 //
2473 TString sLine(line);
2474 if (strstr(line,fantomline)) {
2475 // End-Of-Line action
2476 // See the comment (copied from above):
2477 // It is a "fantom" method to synchronize user keyboard input
2478 // and ROOT prompt line (for WIN32)
2479 // and is implemented by
2480 if (gApplication) {
2481 if (gApplication->IsCmdThread()) {
2483 gROOT->SetLineIsProcessing();
2484
2486
2487 gROOT->SetLineHasBeenProcessed();
2488 }
2489 }
2490 return 0;
2491 }
2492
2494 gGlobalMutex->Lock();
2495 if (!gInterpreterMutex)
2497 gGlobalMutex->UnLock();
2498 }
2500 gROOT->SetLineIsProcessing();
2501
2502 struct InterpreterFlagsRAII {
2503 cling::Interpreter* fInterpreter;
2504 bool fWasDynamicLookupEnabled;
2505
2506 InterpreterFlagsRAII(cling::Interpreter* interp):
2507 fInterpreter(interp),
2508 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2509 {
2510 fInterpreter->enableDynamicLookup(true);
2511 }
2512 ~InterpreterFlagsRAII() {
2513 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2514 gROOT->SetLineHasBeenProcessed();
2515 }
2516 } interpreterFlagsRAII(GetInterpreterImpl());
2517
2518 // A non-zero returned value means the given line was
2519 // not a complete statement.
2520 int indent = 0;
2521 // This will hold the resulting value of the evaluation the given line.
2522 cling::Value result;
2523 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2524 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2525 !strncmp(sLine.Data(), ".X", 2)) {
2526 // If there was a trailing "+", then CINT compiled the code above,
2527 // and we will need to strip the "+" before passing the line to cling.
2528 TString mod_line(sLine);
2529 TString aclicMode;
2530 TString arguments;
2531 TString io;
2532 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2533 aclicMode, arguments, io);
2534 if (aclicMode.Length()) {
2535 // Remove the leading '+'
2536 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2537 aclicMode[0]='k'; // We always want to keep the .so around.
2538 if (aclicMode[1]=='+') {
2539 // We have a 2nd +
2540 aclicMode[1]='f'; // We want to force the recompilation.
2541 }
2542 if (!gSystem->CompileMacro(fname,aclicMode)) {
2543 // ACLiC failed.
2544 compRes = cling::Interpreter::kFailure;
2545 } else {
2546 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2547 // if execution was requested.
2548
2549 if (arguments.Length() == 0) {
2550 arguments = "()";
2551 }
2552 // We need to remove the extension.
2553 Ssiz_t ext = fname.Last('.');
2554 if (ext != kNPOS) {
2555 fname.Remove(ext);
2556 }
2557 const char *function = gSystem->BaseName(fname);
2558 mod_line = function + arguments + io;
2560 }
2561 }
2562 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2563 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2564 if (gSystem->Load(fname) < 0) {
2565 // Loading failed.
2566 compRes = cling::Interpreter::kFailure;
2567 } else {
2568 if (arguments.Length() == 0) {
2569 arguments = "()";
2570 }
2571 // We need to remove the extension. (*.so or *.dll)
2572 Ssiz_t ext = fname.Last('.');
2573 if (ext != kNPOS) {
2574 fname.Remove(ext);
2575 }
2576 // Now we try to find the 'main' function to run within this shared library
2577 // We distinguish two cases: a library.so with a function library(args),
2578 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2579 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2580 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2581 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2582 ext = fname.Last('_');
2583 if (ext != kNPOS) {
2584 fname.Remove(ext);
2585 }
2586 }
2587 const char *function = gSystem->BaseName(fname);
2588 mod_line = function + arguments + io;
2590 }
2591 } else {
2592 // neither ACLiC nor run shared-library (.x)
2593 size_t unnamedMacroOpenCurly;
2594 {
2595 std::string code;
2596 std::string codeline;
2597 // Windows requires std::ifstream::binary to properly handle
2598 // CRLF and LF line endings
2599 std::ifstream in(fname, std::ifstream::binary);
2600 while (in) {
2601 std::getline(in, codeline);
2602 code += codeline + "\n";
2603 }
2604 unnamedMacroOpenCurly
2605 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2606 }
2607
2608 fCurExecutingMacros.push_back(fname);
2609 if (unnamedMacroOpenCurly != std::string::npos) {
2610 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2611 unnamedMacroOpenCurly);
2612 } else {
2613 // No DynLookup for .x, .L of named macros.
2614 fInterpreter->enableDynamicLookup(false);
2616 }
2617 fCurExecutingMacros.pop_back();
2618 }
2619 } // .L / .X / .x
2620 else {
2621 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2622 // explicitly ignore .autodict without having to support it
2623 // in cling.
2624
2625 // Turn off autoparsing if this is an include directive
2626 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2627 if (isInclusionDirective) {
2628 SuspendAutoParsing autoParseRaii(this);
2630 } else {
2632 }
2633 }
2634 }
2635 if (result.isValid())
2637 if (indent) {
2638 if (error)
2639 *error = kProcessing;
2640 return 0;
2641 }
2642 if (error) {
2643 switch (compRes) {
2644 case cling::Interpreter::kSuccess: *error = kNoError; break;
2645 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2646 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2647 }
2648 }
2649 if (compRes == cling::Interpreter::kSuccess
2650 && result.isValid()
2651 && !result.isVoid())
2652 {
2653 return result.castAs<Longptr_t>();
2654 }
2655 return 0;
2656}
2657
2658////////////////////////////////////////////////////////////////////////////////
2659/// No-op; see TRint instead.
2660
2662{
2663}
2664
2665////////////////////////////////////////////////////////////////////////////////
2666/// \brief Add a directory to the list of directories in which the
2667/// interpreter looks for include files.
2668/// \param[in] path The path to the directory.
2669/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2670/// \b NOT supported.
2671/// \warning Only the path to the directory should be specified, without
2672/// prepending the \c -I prefix, i.e.
2673/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2674/// \c -I prefix is used it will be ignored.
2675void TCling::AddIncludePath(const char *path)
2676{
2678 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2679 // gCling->AddIncludePath() does not! Work around that inconsistency:
2680 if (path[0] == '-' && path[1] == 'I')
2681 path += 2;
2682 TString sPath(path);
2683 gSystem->ExpandPathName(sPath);
2684#ifdef _MSC_VER
2685 if (sPath.BeginsWith("/")) {
2686 char drive[3];
2687 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2688 sPath.Prepend(drive);
2689 }
2690#endif
2691 fInterpreter->AddIncludePath(sPath.Data());
2692}
2693
2694////////////////////////////////////////////////////////////////////////////////
2695/// Visit all members over members, recursing over base classes.
2696
2697void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2698 const TClass* cl, Bool_t isTransient)
2699{
2703 }
2704
2705 if (!cl || cl->GetCollectionProxy()) {
2706 // We do not need to investigate the content of the STL
2707 // collection, they are opaque to us (and details are
2708 // uninteresting).
2709 return;
2710 }
2711
2712 static const TClassRef clRefString("std::string");
2713 if (clRefString == cl) {
2714 // We stream std::string without going through members..
2715 return;
2716 }
2717
2718 if (TClassEdit::IsStdArray(cl->GetName())) {
2719 // We treat std arrays as C arrays
2720 return;
2721 }
2722
2723 const char* cobj = (const char*) obj; // for ptr arithmetics
2724
2725 // Treat the case of std::complex in a special manner. We want to enforce
2726 // the layout of a stl implementation independent class, which is the
2727 // complex as implemented in ROOT5.
2728
2729 // A simple lambda to simplify the code
2730 auto inspInspect = [&] (ptrdiff_t offset){
2731 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2732 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2733 };
2734
2735 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2736 switch(complexType) {
2738 {
2739 break;
2740 }
2742 {
2743 inspInspect(sizeof(float));
2744 return;
2745 }
2747 {
2748 inspInspect(sizeof(double));
2749 return;
2750 }
2752 {
2753 inspInspect(sizeof(int));
2754 return;
2755 }
2757 {
2758 inspInspect(sizeof(long));
2759 return;
2760 }
2761 }
2762
2763 static clang::PrintingPolicy
2764 printPol(fInterpreter->getCI()->getLangOpts());
2765 if (printPol.Indentation) {
2766 // not yet initialized
2767 printPol.Indentation = 0;
2768 printPol.SuppressInitializers = true;
2769 }
2770
2771 const char* clname = cl->GetName();
2772 // Printf("Inspecting class %s\n", clname);
2773
2774 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2775 const clang::Decl *scopeDecl = nullptr;
2776 const clang::Type *recordType = nullptr;
2777
2778 if (cl->GetClassInfo()) {
2779 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2780 scopeDecl = clingCI->GetDecl();
2781 recordType = clingCI->GetType();
2782 } else {
2783 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2784 // Diags will complain about private classes:
2785 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2786 &recordType);
2787 }
2788 if (!scopeDecl) {
2789 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2790 return;
2791 }
2792 const clang::CXXRecordDecl* recordDecl
2793 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2794 if (!recordDecl) {
2795 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2796 return;
2797 }
2798
2799 {
2800 // Force possible deserializations first. We need to have no pending
2801 // Transaction when passing control flow to the inspector below (ROOT-7779).
2802 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2803
2804 astContext.getASTRecordLayout(recordDecl);
2805
2806 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2807 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2808 }
2809
2810 const clang::ASTRecordLayout& recLayout
2811 = astContext.getASTRecordLayout(recordDecl);
2812
2813 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2814 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2815 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2816 // cl->GetName());
2817 // }
2818 if (cl->Size() != recLayout.getSize().getQuantity()) {
2819 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2820 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2821 }
2822
2823 unsigned iNField = 0;
2824 // iterate over fields
2825 // FieldDecls are non-static, else it would be a VarDecl.
2826 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2827 eField = recordDecl->field_end(); iField != eField;
2828 ++iField, ++iNField) {
2829
2830
2831 clang::QualType memberQT = iField->getType();
2832 if (recordType) {
2833 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2834 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2835 }
2836 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2837 if (memberQT.isNull()) {
2838 std::string memberName;
2839 llvm::raw_string_ostream stream(memberName);
2840 // Don't trigger fopen of the source file to count lines:
2841 printPol.AnonymousTagLocations = false;
2842 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2843 stream.flush();
2844 Error("InspectMembers",
2845 "Cannot retrieve QualType for member %s while inspecting class %s",
2846 memberName.c_str(), clname);
2847 continue; // skip member
2848 }
2849 const clang::Type* memType = memberQT.getTypePtr();
2850 if (!memType) {
2851 std::string memberName;
2852 llvm::raw_string_ostream stream(memberName);
2853 // Don't trigger fopen of the source file to count lines:
2854 printPol.AnonymousTagLocations = false;
2855 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2856 stream.flush();
2857 Error("InspectMembers",
2858 "Cannot retrieve Type for member %s while inspecting class %s",
2859 memberName.c_str(), clname);
2860 continue; // skip member
2861 }
2862
2863 const clang::Type* memNonPtrType = memType;
2864 Bool_t ispointer = false;
2865 if (memNonPtrType->isPointerType()) {
2866 ispointer = true;
2867 clang::QualType ptrQT
2868 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2869 if (recordType) {
2870 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2871 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2872 }
2873 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2874 if (ptrQT.isNull()) {
2875 std::string memberName;
2876 llvm::raw_string_ostream stream(memberName);
2877 // Don't trigger fopen of the source file to count lines:
2878 printPol.AnonymousTagLocations = false;
2879 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2880 stream.flush();
2881 Error("InspectMembers",
2882 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2883 memberName.c_str(), clname);
2884 continue; // skip member
2885 }
2886 memNonPtrType = ptrQT.getTypePtr();
2887 }
2888
2889 // assemble array size(s): "[12][4][]"
2890 llvm::SmallString<8> arraySize;
2891 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2892 unsigned arrLevel = 0;
2893 bool haveErrorDueToArray = false;
2894 while (arrType) {
2895 ++arrLevel;
2896 arraySize += '[';
2897 const clang::ConstantArrayType* constArrType =
2898 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2899 if (constArrType) {
2900 constArrType->getSize().toStringUnsigned(arraySize);
2901 }
2902 arraySize += ']';
2903 clang::QualType subArrQT = arrType->getElementType();
2904 if (subArrQT.isNull()) {
2905 std::string memberName;
2906 llvm::raw_string_ostream stream(memberName);
2907 // Don't trigger fopen of the source file to count lines:
2908 printPol.AnonymousTagLocations = false;
2909 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2910 stream.flush();
2911 Error("InspectMembers",
2912 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2913 arrLevel, subArrQT.getAsString(printPol).c_str(),
2914 memberName.c_str(), clname);
2915 haveErrorDueToArray = true;
2916 break;
2917 }
2918 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2919 }
2920 if (haveErrorDueToArray) {
2921 continue; // skip member
2922 }
2923
2924 // construct member name
2925 std::string fieldName;
2926 if (memType->isPointerType()) {
2927 fieldName = "*";
2928 }
2929
2930 // Check if this field has a custom ioname, if not, just use the one of the decl
2931 std::string ioname(iField->getName());
2932 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2933 fieldName += ioname;
2934 fieldName += arraySize;
2935
2936 // get member offset
2937 // NOTE currently we do not support bitfield and do not support
2938 // member that are not aligned on 'bit' boundaries.
2939 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2940 ptrdiff_t fieldOffset = offset.getQuantity();
2941
2942 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2943 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2944 // R__insp.InspectMember(fName, "fName.");
2945 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2946
2947 // If the class has a custom streamer and the type of the filed is a
2948 // private enum, struct or class, skip it.
2949 if (!insp.IsTreatingNonAccessibleTypes()){
2950 auto iFiledQtype = iField->getType();
2951 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2952 auto declAccess = tagDecl->getAccess();
2953 if (declAccess == AS_private || declAccess == AS_protected) {
2954 continue;
2955 }
2956 }
2957 }
2958
2959 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2960
2961 if (!ispointer) {
2962 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2963 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2964 // nested objects get an extra call to InspectMember
2965 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2966 std::string sFieldRecName;
2967 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2969 clang::QualType(memNonPtrType,0),
2970 *fInterpreter,
2972 }
2973
2974 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2975 // if we can not find the member (which should not really happen),
2976 // let's consider it transient.
2977 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2978
2979 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2980 (fieldName + '.').c_str(), transient);
2981
2982 }
2983 }
2984 } // loop over fields
2985
2986 // inspect bases
2987 // TNamed::ShowMembers(R__insp);
2988 unsigned iNBase = 0;
2989 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2990 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2991 iBase != eBase; ++iBase, ++iNBase) {
2992 clang::QualType baseQT = iBase->getType();
2993 if (baseQT.isNull()) {
2994 Error("InspectMembers",
2995 "Cannot find QualType for base number %d while inspecting class %s",
2996 iNBase, clname);
2997 continue;
2998 }
2999 const clang::CXXRecordDecl* baseDecl
3000 = baseQT->getAsCXXRecordDecl();
3001 if (!baseDecl) {
3002 Error("InspectMembers",
3003 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3004 iNBase, clname);
3005 continue;
3006 }
3007 TClass* baseCl=nullptr;
3008 std::string sBaseName;
3009 // Try with the DeclId
3010 std::vector<TClass*> foundClasses;
3011 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3012 if (foundClasses.size()==1){
3013 baseCl=foundClasses[0];
3014 } else {
3015 // Try with the normalised Name, as a fallback
3016 if (!baseCl){
3018 baseQT,
3019 *fInterpreter,
3021 baseCl = TClass::GetClass(sBaseName.c_str());
3022 }
3023 }
3024
3025 if (!baseCl){
3026 std::string qualNameForDiag;
3027 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3028 Error("InspectMembers",
3029 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3030 continue;
3031 }
3032
3033 int64_t baseOffset;
3034 if (iBase->isVirtual()) {
3036 if (!isTransient) {
3037 Error("InspectMembers",
3038 "Base %s of class %s is virtual but no object provided",
3039 sBaseName.c_str(), clname);
3040 }
3042 } else {
3043 // We have an object to determine the vbase offset.
3045 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3046 if (ci && baseCi) {
3047 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3048 true /*isDerivedObj*/);
3049 if (baseOffset == -1) {
3050 Error("InspectMembers",
3051 "Error calculating offset of virtual base %s of class %s",
3052 sBaseName.c_str(), clname);
3053 }
3054 } else {
3055 Error("InspectMembers",
3056 "Cannot calculate offset of virtual base %s of class %s",
3057 sBaseName.c_str(), clname);
3058 continue;
3059 }
3060 }
3061 } else {
3062 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3063 }
3064 // TOFIX: baseCl can be null here!
3065 if (baseCl->IsLoaded()) {
3066 // For loaded class, CallShowMember will (especially for TObject)
3067 // call the virtual ShowMember rather than the class specific version
3068 // resulting in an infinite recursion.
3069 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3070 } else {
3071 baseCl->CallShowMembers(cobj + baseOffset,
3072 insp, isTransient);
3073 }
3074 } // loop over bases
3075}
3076
3077////////////////////////////////////////////////////////////////////////////////
3078/// Reset the interpreter internal state in case a previous action was not correctly
3079/// terminated.
3080
3082{
3083 // No-op there is not equivalent state (to be cleared) in Cling.
3084}
3085
3086////////////////////////////////////////////////////////////////////////////////
3087/// Delete existing temporary values.
3088
3090{
3091 // No-op for cling due to cling::Value.
3092}
3093
3094////////////////////////////////////////////////////////////////////////////////
3095/// Declare code to the interpreter, without any of the interpreter actions
3096/// that could trigger a re-interpretation of the code. I.e. make cling
3097/// behave like a compiler: no dynamic lookup, no input wrapping for
3098/// subsequent execution, no automatic provision of declarations but just a
3099/// plain `#include`.
3100/// Returns true on success, false on failure.
3101
3102bool TCling::Declare(const char* code)
3103{
3105
3106 SuspendAutoLoadingRAII autoLoadOff(this);
3107 SuspendAutoParsing autoParseRaii(this);
3108
3109 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3110 fInterpreter->enableDynamicLookup(false);
3111 bool oldRawInput = fInterpreter->isRawInputEnabled();
3112 fInterpreter->enableRawInput(true);
3113
3114 Bool_t ret = LoadText(code);
3115
3116 fInterpreter->enableRawInput(oldRawInput);
3117 fInterpreter->enableDynamicLookup(oldDynLookup);
3118 return ret;
3119}
3120
3121////////////////////////////////////////////////////////////////////////////////
3122/// It calls a "fantom" method to synchronize user keyboard input
3123/// and ROOT prompt line.
3124
3129
3130// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3131// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3132// was already taking a lock.
3133static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3134{
3135 // Check shared library.
3136 TString tLibName(libname);
3137 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3138 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3139 return false;
3140}
3141
3142Bool_t TCling::IsLibraryLoaded(const char* libname) const
3143{
3145 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3146}
3147
3148////////////////////////////////////////////////////////////////////////////////
3149/// Return true if ROOT has cxxmodules pcm for a given library name.
3150// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3151Bool_t TCling::HasPCMForLibrary(const char *libname) const
3152{
3153 llvm::StringRef ModuleName(libname);
3154 ModuleName = llvm::sys::path::stem(ModuleName);
3155 ModuleName.consume_front("lib");
3156
3157 // FIXME: In case when the modulemap is not yet loaded we will return the
3158 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3159 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3160 // which may happen after calling this interface. Maybe we should also check
3161 // if there is a Event.pcm file and a module.modulemap, load it and return
3162 // true.
3163 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3164 clang::Module *M = moduleMap.findModule(ModuleName);
3165 return M && !M->IsUnimportable && M->getASTFile();
3166}
3167
3168////////////////////////////////////////////////////////////////////////////////
3169/// Return true if the file has already been loaded by cint.
3170/// We will try in this order:
3171/// actual filename
3172/// filename as a path relative to
3173/// the include path
3174/// the shared library path
3175
3177{
3179
3180 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3181 // cling::DynamicLibraryManager.
3182
3183 std::string file_name = filename;
3184 size_t at = std::string::npos;
3185 while ((at = file_name.find("/./")) != std::string::npos)
3186 file_name.replace(at, 3, "/");
3187
3188 std::string filesStr = "";
3189 llvm::raw_string_ostream filesOS(filesStr);
3190 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3191 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3192 filesOS.flush();
3193
3194 llvm::SmallVector<llvm::StringRef, 100> files;
3195 llvm::StringRef(filesStr).split(files, "\n");
3196
3197 std::set<std::string> fileMap;
3198 llvm::StringRef file_name_ref(file_name);
3199 // Fill fileMap; return early on exact match.
3200 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3201 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3202 if ((*iF) == file_name_ref) return kTRUE; // exact match
3203 fileMap.insert(iF->str());
3204 }
3205
3206 if (fileMap.empty()) return kFALSE;
3207
3208 // Check MacroPath.
3209 TString sFilename(file_name.c_str());
3210 if (gSystem->FindFile(TROOT::GetMacroPath(), sFilename, kReadPermission)
3211 && fileMap.count(sFilename.Data())) {
3212 return kTRUE;
3213 }
3214
3215 // Check IncludePath.
3216 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3217 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3218 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3219 while (incPath.Index(" :") != -1) {
3220 incPath.ReplaceAll(" :", ":");
3221 }
3222 incPath.Prepend(".:");
3223 sFilename = file_name.c_str();
3224 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3225 && fileMap.count(sFilename.Data())) {
3226 return kTRUE;
3227 }
3228
3229 // Check shared library.
3230 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3231 return kTRUE;
3232
3233 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3234 clang::ConstSearchDirIterator *CurDir = nullptr;
3235 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3236 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3237 auto FE = HS.LookupFile(file_name.c_str(),
3238 clang::SourceLocation(),
3239 /*isAngled*/ false,
3240 /*FromDir*/ nullptr, CurDir,
3241 clang::ArrayRef<std::pair<const clang::FileEntry *,
3242 const clang::DirectoryEntry *>>(),
3243 /*SearchPath*/ nullptr,
3244 /*RelativePath*/ nullptr,
3245 /*RequestingModule*/ nullptr,
3246 /*SuggestedModule*/ nullptr,
3247 /*IsMapped*/ nullptr,
3248 /*IsFrameworkFound*/ nullptr,
3249 /*SkipCache*/ false,
3250 /*BuildSystemModule*/ false,
3251 /*OpenFile*/ false,
3252 /*CacheFail*/ false);
3253 if (FE) {
3254 // check in the source manager if the file is actually loaded
3255 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3256 // this works only with header (and source) files...
3257 clang::FileID FID = SM.translateFile(*FE);
3258 if (!FID.isInvalid() && FID.getHashValue() == 0)
3259 return kFALSE;
3260 else {
3261 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3262 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3263 return kFALSE;
3264 if (!FID.isInvalid())
3265 return kTRUE;
3266 }
3267 // ...then check shared library again, but with full path now
3268 sFilename = FE->getName().str();
3269 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3270 && fileMap.count(sFilename.Data())) {
3271 return kTRUE;
3272 }
3273 }
3274 return kFALSE;
3275}
3276
3277
3278#if defined(R__MACOSX)
3279
3280////////////////////////////////////////////////////////////////////////////////
3281/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3282/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3283/// to `-lFOO` such that it can be passed to the linker.
3284/// This is a unique feature of macOS 11.
3285
3286static bool R__UpdateLibFileForLinking(TString &lib)
3287{
3288 const char *mapfile = nullptr;
3289#if __x86_64__
3290 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3291#elif __arm64__
3292 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3293#else
3294 #error unsupported architecture
3295#endif
3296 if (std::ifstream cacheMap{mapfile}) {
3297 std::string line;
3298 while (getline(cacheMap, line)) {
3299 if (line.find(lib) != std::string::npos) {
3300 lib.ReplaceAll("/usr/lib/lib","-l");
3301 lib.ReplaceAll(".dylib","");
3302 return true;
3303 }
3304 }
3305 return false;
3306 }
3307 return false;
3308}
3309#endif // R__MACOSX
3310
3311#if defined (R__LINUX) || defined (R__FBSD)
3312
3313////////////////////////////////////////////////////////////////////////////////
3314/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3315/// Collects opened libraries.
3316
3317static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3318{
3319 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3320 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3321
3322 auto newLibs = static_cast<std::vector<std::string>*>(data);
3323 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3324 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3325 if (info->dlpi_name && info->dlpi_name[0]
3326#if defined(R__FBSD)
3327 //skip the executable (with null addr)
3328 && info->dlpi_addr
3329 //has no path
3330 && strncmp(info->dlpi_name, "[vdso]", 6)
3331 //the linker does not like to be mmapped
3332 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3333 //with error message "mmap of entire address space failed: Cannot allocate memory"
3334 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3335#endif
3336 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3337 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3338 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3339 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3340 newLibs->emplace_back(info->dlpi_name);
3341 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3342 }
3343 // No matter what the doc says, return != 0 means "stop the iteration".
3344 return 0;
3345}
3346
3347#endif // R__LINUX || R__FBSD
3348
3349
3350////////////////////////////////////////////////////////////////////////////////
3351
3353{
3354#if defined(R__WIN32) || defined(__CYGWIN__)
3355 HMODULE hModules[1024];
3356 void *hProcess;
3357 unsigned long cbModules;
3358 unsigned int i;
3359 hProcess = (void *)::GetCurrentProcess();
3360 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3361 // start at 1 to skip the executable itself
3362 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3363 static const int bufsize = 260;
3364 wchar_t winname[bufsize];
3365 char posixname[bufsize];
3366 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3367#if defined(__CYGWIN__)
3368 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3369#else
3370 std::wstring wpath = winname;
3371 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3372 string path(wpath.begin(), wpath.end());
3373 strncpy(posixname, path.c_str(), bufsize);
3374#endif
3375 if (!fSharedLibs.Contains(posixname)) {
3376 RegisterLoadedSharedLibrary(posixname);
3377 }
3378 }
3379#elif defined(R__MACOSX)
3380 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3381 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3382
3383 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3384 // Skip non-dylibs
3385 if (mh->filetype == MH_DYLIB) {
3386 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3387 RegisterLoadedSharedLibrary(imageName);
3388 }
3389 }
3390
3391 ++imageIndex;
3392 }
3393 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3394#elif defined(R__LINUX) || defined(R__FBSD)
3395 // fPrevLoadedDynLibInfo is unused on Linux.
3396 (void) fPrevLoadedDynLibInfo;
3397
3398 std::vector<std::string> newLibs;
3399 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3400 for (auto &&lib: newLibs)
3401 RegisterLoadedSharedLibrary(lib.c_str());
3402#else
3403 Error("TCling::UpdateListOfLoadedSharedLibraries",
3404 "Platform not supported!");
3405#endif
3406}
3407
3408namespace {
3409template <int N>
3410static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3411 return !strncmp(haystack, needle, N - 1);
3412}
3413}
3414
3415////////////////////////////////////////////////////////////////////////////////
3416/// Register a new shared library name with the interpreter; add it to
3417/// fSharedLibs.
3418
3420{
3421 // Ignore NULL filenames, aka "the process".
3422 if (!filename) return;
3423
3424 // Tell the interpreter that this library is available; all libraries can be
3425 // used to resolve symbols.
3426 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3427 if (!DLM->isLibraryLoaded(filename)) {
3428 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3429 }
3430
3431#if defined(R__MACOSX)
3432 // Check that this is not a system library that does not exist on disk.
3433 auto lenFilename = strlen(filename);
3434 auto isInMacOSSystemDir = [](const char *fn) {
3435 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3436 };
3437 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3438
3439 // These we should not link with (e.g. because they forward to .tbd):
3440 || StartsWithStrLit(filename, "/usr/lib/system/")
3441 || StartsWithStrLit(filename, "/usr/lib/libc++")
3442 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3443 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3444 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3445 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3446 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3447 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3448 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3449 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3450 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3451 || StartsWithStrLit(filename, "/usr/lib/libauto")
3452 || StartsWithStrLit(filename, "/usr/lib/libcups")
3453 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3454 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3455 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3456 || StartsWithStrLit(filename, "/usr/lib/libpam")
3457 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3458 || StartsWithStrLit(filename, "/usr/lib/libextension")
3459 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3460 || StartsWithStrLit(filename, "/usr/lib/liboah")
3461 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3462 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3463 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3464 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3465
3466 // The system lib is likely in macOS's blob.
3467 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3468
3469 // "Link against the umbrella framework 'System.framework' instead"
3470 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3471 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3472 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3473
3474 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3475 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3476 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3477 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3478 return;
3479 TString sFileName(filename);
3480 R__UpdateLibFileForLinking(sFileName);
3481 filename = sFileName.Data();
3482#elif defined(__CYGWIN__)
3483 // Check that this is not a system library
3484 static const int bufsize = 260;
3485 char posixwindir[bufsize];
3486 char *windir = getenv("WINDIR");
3487 if (windir)
3488 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3489 else
3490 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3491 if (strstr(filename, posixwindir) ||
3492 strstr(filename, "/usr/bin/cyg"))
3493 return;
3494#elif defined(R__WIN32)
3495 if (strstr(filename, "/Windows/"))
3496 return;
3497#elif defined (R__LINUX)
3498 if (strstr(filename, "/ld-linux")
3499 || strstr(filename, "linux-gnu/")
3500 || strstr(filename, "/libstdc++.")
3501 || strstr(filename, "/libgcc")
3502 || strstr(filename, "/libc.")
3503 || strstr(filename, "/libdl.")
3504 || strstr(filename, "/libm."))
3505 return;
3506#endif
3507 // Update string of available libraries.
3508 if (!fSharedLibs.IsNull()) {
3509 fSharedLibs.Append(" ");
3510 }
3511 fSharedLibs.Append(filename);
3512}
3513
3514////////////////////////////////////////////////////////////////////////////////
3515/// Load a library file in cling's memory.
3516/// if 'system' is true, the library is never unloaded.
3517/// Return 0 on success, -1 on failure.
3518
3519Int_t TCling::Load(const char* filename, Bool_t system)
3520{
3521 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3522
3523 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3525 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3526 std::string canonLib = DLM->lookupLibrary(filename);
3527 cling::DynamicLibraryManager::LoadLibResult res
3528 = cling::DynamicLibraryManager::kLoadLibNotFound;
3529 if (!canonLib.empty()) {
3530 if (system)
3531 res = DLM->loadLibrary(filename, system, true);
3532 else {
3533 // For the non system libs, we'd like to be able to unload them.
3534 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3535 cling::Interpreter::CompilationResult compRes;
3536 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3537 if (compRes == cling::Interpreter::kSuccess)
3538 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3539 }
3540 }
3541
3542 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3544 }
3545 switch (res) {
3546 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3547 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3548 default: break;
3549 };
3550 return -1;
3551}
3552
3553////////////////////////////////////////////////////////////////////////////////
3554/// Load a macro file in cling's memory.
3555
3556void TCling::LoadMacro(const char* filename, EErrorCode* error)
3557{
3558 ProcessLine(Form(".L %s", filename), error);
3559}
3560
3561////////////////////////////////////////////////////////////////////////////////
3562/// Let cling process a command line asynch.
3563
3565{
3566 return ProcessLine(line, error);
3567}
3568
3569////////////////////////////////////////////////////////////////////////////////
3570/// Let cling process a command line synchronously, i.e we are waiting
3571/// it will be finished.
3572
3574{
3576 if (gApplication) {
3577 if (gApplication->IsCmdThread()) {
3578 return ProcessLine(line, error);
3579 }
3580 return 0;
3581 }
3582 return ProcessLine(line, error);
3583}
3584
3585////////////////////////////////////////////////////////////////////////////////
3586/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3587/// however not declarations, like "Int_t x;").
3588
3590{
3591#ifdef R__WIN32
3592 // Test on ApplicationImp not being 0 is needed because only at end of
3593 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3594 // we can not use it.
3595 if (gApplication && gApplication->GetApplicationImp()) {
3596 while (gROOT->IsLineProcessing() && !gApplication) {
3597 Warning("Calc", "waiting for cling thread to free");
3598 gSystem->Sleep(500);
3599 }
3600 gROOT->SetLineIsProcessing();
3601 }
3602#endif // R__WIN32
3604 if (error) {
3605 *error = TInterpreter::kNoError;
3606 }
3607 cling::Value valRef;
3608 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3609 try {
3610 cr = fInterpreter->evaluate(line, valRef);
3611 }
3612 catch (cling::InterpreterException& ex)
3613 {
3614 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3615 ex.diagnose();
3616 cr = cling::Interpreter::kFailure;
3617 }
3618
3619 if (cr != cling::Interpreter::kSuccess) {
3620 // Failure in compilation.
3621 if (error) {
3622 // Note: Yes these codes are weird.
3624 }
3625 return 0L;
3626 }
3627 if (!valRef.isValid()) {
3628 // Failure at runtime.
3629 if (error) {
3630 // Note: Yes these codes are weird.
3631 *error = TInterpreter::kDangerous;
3632 }
3633 return 0L;
3634 }
3635
3636 if (valRef.isVoid()) {
3637 return 0;
3638 }
3639
3640 RegisterTemporary(valRef);
3641#ifdef R__WIN32
3642 if (gApplication && gApplication->GetApplicationImp()) {
3643 gROOT->SetLineHasBeenProcessed();
3644 }
3645#endif // R__WIN32
3646 return valRef.castAs<Longptr_t>();
3647}
3648
3649////////////////////////////////////////////////////////////////////////////////
3650/// Set a getline function to call when input is needed.
3651
3652void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3653 void (*histaddFunc)(const char* line))
3654{
3655 // If cling offers a replacement for G__pause(), it would need to
3656 // also offer a way to customize at least the history recording.
3657
3658#if defined(R__MUST_REVISIT)
3659#if R__MUST_REVISIT(6,2)
3660 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3661#endif
3662#endif
3663}
3664
3665////////////////////////////////////////////////////////////////////////////////
3666/// Helper function to increase the internal Cling count of transactions
3667/// that change the AST.
3668
3669Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3670{
3672
3673 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3674 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3675 || T.macros_begin() != T.macros_end()
3676 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3678 return true;
3679 }
3680 return false;
3681}
3682
3683////////////////////////////////////////////////////////////////////////////////
3684/// Delete object from cling symbol table so it can not be used anymore.
3685/// cling objects are always on the heap.
3686
3688{
3689 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3690 // put in place the Read/Write part here. Keeping the write lock
3691 // here is 'catasptrophic' for scaling as it means that ALL calls
3692 // to RecursiveRemove will take the write lock and performance
3693 // of many threads trying to access the write lock at the same
3694 // time is relatively bad.
3696 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3697 // (but isn't at the moment).
3698 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3699 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3700 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3702 DeleteGlobal(obj);
3703 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3704 }
3705 }
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Pressing Ctrl+C should forward here. In the case where we have had
3710/// continuation requested we must reset it.
3711
3713{
3714 fMetaProcessor->cancelContinuation();
3715 // Reset the Cling state to the state saved by the last call to
3716 // TCling::SaveContext().
3717#if defined(R__MUST_REVISIT)
3718#if R__MUST_REVISIT(6,2)
3720 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3721#endif
3722#endif
3723}
3724
3725////////////////////////////////////////////////////////////////////////////////
3726/// Reset the Cling state to its initial state.
3727
3729{
3730#if defined(R__MUST_REVISIT)
3731#if R__MUST_REVISIT(6,2)
3733 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3734#endif
3735#endif
3736}
3737
3738////////////////////////////////////////////////////////////////////////////////
3739/// Reset in Cling the list of global variables to the state saved by the last
3740/// call to TCling::SaveGlobalsContext().
3741///
3742/// Note: Right now, all we do is run the global destructors.
3743
3745{
3747 // TODO:
3748 // Here we should iterate over the transactions (N-3) and revert.
3749 // N-3 because the first three internal to cling.
3750
3751 fInterpreter->runAndRemoveStaticDestructors();
3752}
3753
3754////////////////////////////////////////////////////////////////////////////////
3755/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3756/// call to TCling::SaveGlobalsContext().
3757
3759{
3760#if defined(R__MUST_REVISIT)
3761#if R__MUST_REVISIT(6,2)
3763 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3764#endif
3765#endif
3766}
3767
3768////////////////////////////////////////////////////////////////////////////////
3769/// Rewind Cling dictionary to the point where it was before executing
3770/// the current macro. This function is typically called after SEGV or
3771/// ctlr-C after doing a longjmp back to the prompt.
3772
3774{
3775#if defined(R__MUST_REVISIT)
3776#if R__MUST_REVISIT(6,2)
3778 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3779#endif
3780#endif
3781}
3782
3783////////////////////////////////////////////////////////////////////////////////
3784/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3785/// Returns 1 in case of success and 0 in case object was not in table.
3786
3788{
3789#if defined(R__MUST_REVISIT)
3790#if R__MUST_REVISIT(6,2)
3792 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3793#endif
3794#endif
3795 return 0;
3796}
3797
3798////////////////////////////////////////////////////////////////////////////////
3799/// Undeclare obj called name.
3800/// Returns 1 in case of success, 0 for failure.
3801
3803{
3804#if defined(R__MUST_REVISIT)
3805#if R__MUST_REVISIT(6,2)
3806 Warning("DeleteVariable","should do more that just reseting the value to zero");
3807#endif
3808#endif
3809
3811 llvm::StringRef srName(name);
3812 const char* unscopedName = name;
3813 llvm::StringRef::size_type posScope = srName.rfind("::");
3814 const clang::DeclContext* declCtx = nullptr;
3815 if (posScope != llvm::StringRef::npos) {
3816 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3817 const clang::Decl* scopeDecl
3818 = lh.findScope(srName.substr(0, posScope),
3819 cling::LookupHelper::WithDiagnostics);
3820 if (!scopeDecl) {
3821 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3822 name);
3823 return 0;
3824 }
3825 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3826 if (!declCtx) {
3827 Error("DeleteVariable",
3828 "Enclosing scope for variable %s is not a declaration context",
3829 name);
3830 return 0;
3831 }
3832 unscopedName += posScope + 2;
3833 }
3834 // Could trigger deserialization of decls.
3835 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3836 clang::NamedDecl* nVarDecl
3837 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3838 if (!nVarDecl) {
3839 Error("DeleteVariable", "Unknown variable %s", name);
3840 return 0;
3841 }
3842 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3843 if (!varDecl) {
3844 Error("DeleteVariable", "Entity %s is not a variable", name);
3845 return 0;
3846 }
3847
3848 clang::QualType qType = varDecl->getType();
3849 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3850 // Cannot set a reference's address to nullptr; the JIT can place it
3851 // into read-only memory (ROOT-7100).
3852 if (type->isPointerType()) {
3853 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3854 // set pointer to invalid.
3855 if (ppInt) *ppInt = nullptr;
3856 }
3857 return 1;
3858}
3859
3860////////////////////////////////////////////////////////////////////////////////
3861/// Save the current Cling state.
3862
3864{
3865#if defined(R__MUST_REVISIT)
3866#if R__MUST_REVISIT(6,2)
3868 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3869#endif
3870#endif
3871}
3872
3873////////////////////////////////////////////////////////////////////////////////
3874/// Save the current Cling state of global objects.
3875
3877{
3878#if defined(R__MUST_REVISIT)
3879#if R__MUST_REVISIT(6,2)
3881 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3882#endif
3883#endif
3884}
3885
3886////////////////////////////////////////////////////////////////////////////////
3887/// No op: see TClingCallbacks (used to update the list of globals)
3888
3892
3893////////////////////////////////////////////////////////////////////////////////
3894/// No op: see TClingCallbacks (used to update the list of global functions)
3895
3899
3900////////////////////////////////////////////////////////////////////////////////
3901/// No op: see TClingCallbacks (used to update the list of types)
3902
3904{
3905}
3906
3907////////////////////////////////////////////////////////////////////////////////
3908/// Check in what order the member of a tuple are layout.
3914
3920
3926
3928{
3929 std::tuple<int,double> value;
3932
3933 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3934 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3935
3936 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3937 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3938
3939 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3940 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3941
3942 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3944 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3946 } else {
3948 }
3949}
3950
3951static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3952{
3953 TClassEdit::TSplitType tupleContent(classname);
3954 std::string alternateName = "TEmulatedTuple";
3955 alternateName.append( classname + 5 );
3956
3957 std::string fullname = "ROOT::Internal::" + alternateName;
3958 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3959 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3960 return fullname;
3961
3962 {
3963 // Check if we can produce the tuple
3964 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3965 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3966 auto deleter = [](TypeInfo_t *type) {
3967 gInterpreter->TypeInfo_Delete(type);
3968 };
3969 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
3970 while (iter != theEnd) {
3971 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
3972 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
3973 if (!silent)
3974 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
3975 classname, iter->c_str());
3976 return "";
3977 }
3978 ++iter;
3979 }
3980 }
3981
3982 std::string guard_name;
3983 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3984 std::ostringstream guard;
3985 guard << "ROOT_INTERNAL_TEmulated_";
3986 guard << guard_name;
3987
3988 std::ostringstream alternateTuple;
3989 alternateTuple << "#ifndef " << guard.str() << "\n";
3990 alternateTuple << "#define " << guard.str() << "\n";
3991 alternateTuple << "namespace ROOT { namespace Internal {\n";
3992 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3993 alternateTuple << "template <> struct " << alternateName << " {\n";
3994
3995 // This could also be a compile time choice ...
3996 switch(IsTupleAscending()) {
3998 unsigned int nMember = 0;
3999 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4000 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4001 while (iter != theEnd) {
4002 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4003 ++iter;
4004 ++nMember;
4005 }
4006 break;
4007 }
4009 unsigned int nMember = tupleContent.fElements.size() - 3;
4010 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4011 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4012 while (iter != theEnd) {
4013 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4014 ++iter;
4015 --nMember;
4016 }
4017 break;
4018 }
4020 Fatal("TCling::SetClassInfo::AlternateTuple",
4021 "Layout of std::tuple on this platform is unexpected.");
4022 break;
4023 }
4024 }
4025
4026 alternateTuple << "};\n";
4027 alternateTuple << "}}\n";
4028 alternateTuple << "#endif\n";
4029 if (!gCling->Declare(alternateTuple.str().c_str()))
4030 {
4031 // Declare is not silent (yet?), so add an explicit error message
4032 // to indicate the consequence of the syntax errors.
4033 Error("Load","Could not declare %s",alternateName.c_str());
4034 return "";
4035 }
4036 alternateName = "ROOT::Internal::" + alternateName;
4037 return alternateName;
4038}
4039
4040////////////////////////////////////////////////////////////////////////////////
4041/// Set pointer to the TClingClassInfo in TClass.
4042/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4043/// already have one.
4044
4045void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4046{
4047 // We are shutting down, there is no point in reloading, it only triggers
4048 // redundant deserializations.
4049 if (fIsShuttingDown) {
4050 // Remove the decl_id from the DeclIdToTClass map
4051 if (cl->fClassInfo) {
4053 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4054 // Test again as another thread may have set fClassInfo to nullptr.
4055 if (TClinginfo) {
4056 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4057 }
4058 delete TClinginfo;
4059 cl->fClassInfo = nullptr;
4060 }
4061 return;
4062 }
4063
4065 if (cl->fClassInfo && !reload) {
4066 return;
4067 }
4068 //Remove the decl_id from the DeclIdToTClass map
4069 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4070 if (TClinginfo) {
4071 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4072 }
4073 delete TClinginfo;
4074 cl->fClassInfo = nullptr;
4075 std::string name(cl->GetName());
4076
4077 auto SetWithoutClassInfoState = [](TClass *cl)
4078 {
4079 if (cl->fState != TClass::kHasTClassInit) {
4080 if (cl->fStreamerInfo->GetEntries() != 0) {
4082 } else {
4084 }
4085 }
4086 };
4087 // Handle the special case of 'tuple' where we ignore the real implementation
4088 // details and just overlay a 'simpler'/'simplistic' version that is easy
4089 // for the I/O to understand and handle.
4090 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4091 if (!reload)
4092 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4093 if (reload || name.empty()) {
4094 // We could not generate the alternate
4095 SetWithoutClassInfoState(cl);
4096 return;
4097 }
4098 }
4099
4100 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4101 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4102 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4103 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4104 // TClingClassInfoReadOnly.
4105 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4106 if (!info->IsValid()) {
4107 SetWithoutClassInfoState(cl);
4108 delete info;
4109 return;
4110 }
4111 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4112 // In case a class contains an external enum, the enum will be seen as a
4113 // class. We must detect this special case and make the class a Zombie.
4114 // Here we assume that a class has at least one method.
4115 // We can NOT call TClass::Property from here, because this method
4116 // assumes that the TClass is well formed to do a lot of information
4117 // caching. The method SetClassInfo (i.e. here) is usually called during
4118 // the building phase of the TClass, hence it is NOT well formed yet.
4119 Bool_t zombieCandidate = kFALSE;
4120 if (
4121 info->IsValid() &&
4122 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4123 ) {
4124 zombieCandidate = kTRUE;
4125 }
4126 if (!info->IsLoaded()) {
4127 if (info->Property() & (kIsNamespace)) {
4128 // Namespaces can have info but no corresponding CINT dictionary
4129 // because they are auto-created if one of their contained
4130 // classes has a dictionary.
4131 zombieCandidate = kTRUE;
4132 }
4133 // this happens when no dictionary is available
4134 delete info;
4135 cl->fClassInfo = nullptr;
4136 }
4137 if (zombieCandidate && !cl->GetCollectionType()) {
4138 cl->MakeZombie();
4139 }
4140 // If we reach here, the info was valid (See early returns).
4141 if (cl->fState != TClass::kHasTClassInit) {
4142 if (cl->fClassInfo) {
4144 } else {
4145// if (TClassEdit::IsSTLCont(cl->GetName()) {
4146// There will be an emulated collection proxy, is that the same?
4147// cl->fState = TClass::kEmulated;
4148// } else {
4149 if (cl->fStreamerInfo->GetEntries() != 0) {
4151 } else {
4153 }
4154// }
4155 }
4156 }
4157 if (cl->fClassInfo) {
4158 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4159 }
4160}
4161
4162////////////////////////////////////////////////////////////////////////////////
4163/// Checks if an entity with the specified name is defined in Cling.
4164/// Returns kUnknown if the entity is not defined.
4165/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4166/// Returns kKnown if the entity is defined.
4167///
4168/// By default, structs, namespaces, classes, enums and unions are looked for.
4169/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4170/// namespaces only are considered. I.e. if the name is an enum or a union,
4171/// the returned value is false.
4172///
4173/// In the case where the class is not loaded and belongs to a namespace
4174/// or is nested, looking for the full class name is outputting a lots of
4175/// (expected) error messages. Currently the only way to avoid this is to
4176/// specifically check that each level of nesting is already loaded.
4177/// In case of templates the idea is that everything between the outer
4178/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4179
4181TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4182{
4184 static const char *anonEnum = "anonymous enum ";
4185 static const int cmplen = strlen(anonEnum);
4186
4187 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4188 return kUnknown;
4189 }
4190
4191 // Do not turn on the AutoLoading if it is globally off.
4192 autoload = autoload && IsClassAutoLoadingEnabled();
4193
4194 // Avoid the double search below in case the name is a fundamental type
4195 // or typedef to a fundamental type.
4196 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4197 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4198
4199 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4200 && fundType->GetType() > 0) {
4201 // Fundamental type, no a class.
4202 return kUnknown;
4203 }
4204
4205 // Migrated from within TClass::GetClass
4206 // If we want to know if a class or a namespace with this name exists in the
4207 // interpreter and this is an enum in the type system, before or after loading
4208 // according to the autoload function argument, return kUnknown.
4209 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4210 return kUnknown;
4211
4212 const char *classname = name;
4213
4214 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4215 class MaybeSuspendAutoLoadParse {
4216 int fStoreAutoLoad = 0;
4217 int fStoreAutoParse = 0;
4218 bool fSuspendedAutoParse = false;
4219 public:
4220 MaybeSuspendAutoLoadParse(int autoload) {
4221 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4222 }
4223
4224 void SuspendAutoParsing() {
4225 fSuspendedAutoParse = true;
4226 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4227 }
4228
4229 ~MaybeSuspendAutoLoadParse() {
4230 if (fSuspendedAutoParse)
4231 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4232 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4233 }
4234 };
4235
4236 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4237 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4238 autoLoadParseRAII.SuspendAutoParsing();
4239
4240 // First we want to check whether the decl exist, but _without_
4241 // generating any template instantiation. However, the lookup
4242 // still will create a forward declaration of the class template instance
4243 // if it exist. In this case, the return value of findScope will still
4244 // be zero but the type will be initialized.
4245 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4246 // this forward declaration.
4247 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4248 const clang::Type *type = nullptr;
4249 const clang::Decl *decl
4250 = lh.findScope(classname,
4251 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4252 : cling::LookupHelper::NoDiagnostics,
4253 &type, /* intantiateTemplate= */ false );
4254 if (!decl) {
4255 std::string buf = TClassEdit::InsertStd(classname);
4256 decl = lh.findScope(buf,
4257 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4258 : cling::LookupHelper::NoDiagnostics,
4259 &type,false);
4260 }
4261
4262 if (type) {
4263 // If decl==0 and the type is valid, then we have a forward declaration.
4264 if (!decl) {
4265 // If we have a forward declaration for a class template instantiation,
4266 // we want to ignore it if it was produced/induced by the call to
4267 // findScope, however we can not distinguish those from the
4268 // instantiation induce by 'soft' use (and thus also induce by the
4269 // same underlying code paths)
4270 // ['soft' use = use not requiring a complete definition]
4271 // So to reduce the amount of disruption to the existing code we
4272 // would just ignore those for STL collection, for which we really
4273 // need to have the compiled collection proxy (and thus the TClass
4274 // bootstrap).
4275 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4276 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4277 (type->getAsCXXRecordDecl());
4278 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4279 // Since the point of instantiation is invalid, we 'guess' that
4280 // the 'instantiation' of the forwarded type appended in
4281 // findscope.
4282 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4283 // For STL Collection we return kUnknown.
4284 return kUnknown;
4285 }
4286 }
4287 }
4289 if (!tci.IsValid()) {
4290 return kUnknown;
4291 }
4292 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4294
4295 if (tci.Property() & propertiesMask) {
4296 bool hasClassDefInline = false;
4297 if (isClassOrNamespaceOnly) {
4298 // We do not need to check for ClassDefInline when this is called from
4299 // TClass::Init, we only do it for the call from TClass::GetClass.
4300 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4301 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4302
4303 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4304 int lineNumber = 0;
4305 bool success = false;
4306 std::tie(success, lineNumber) =
4307 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4308 hasClassDefInline = success && (lineNumber == -1);
4309 }
4310 }
4311
4312 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4313 // , hasClassDefInline);
4314
4315 // We are now sure that the entry is not in fact an autoload entry.
4316 if (hasClassDefInline)
4317 return kWithClassDefInline;
4318 else
4319 return kKnown;
4320 } else {
4321 // We are now sure that the entry is not in fact an autoload entry.
4322 return kUnknown;
4323 }
4324 }
4325
4326 if (decl)
4327 return kKnown;
4328 else
4329 return kUnknown;
4330
4331 // Setting up iterator part of TClingTypedefInfo is too slow.
4332 // Copy the lookup code instead:
4333 /*
4334 TClingTypedefInfo t(fInterpreter, name);
4335 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4336 delete[] classname;
4337 return kTRUE;
4338 }
4339 */
4340
4341// const clang::Decl *decl = lh.findScope(name);
4342// if (!decl) {
4343// std::string buf = TClassEdit::InsertStd(name);
4344// decl = lh.findScope(buf);
4345// }
4346
4347// return (decl);
4348}
4349
4350////////////////////////////////////////////////////////////////////////////////
4351/// Return true if there is a class template by the given name ...
4352
4354{
4355 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4356 // Interpreter transaction ahead, needs locking
4358 const clang::Decl *decl
4359 = lh.findClassTemplate(name,
4360 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4361 : cling::LookupHelper::NoDiagnostics);
4362 if (!decl) {
4363 std::string strname = "std::";
4364 strname += name;
4365 decl = lh.findClassTemplate(strname,
4366 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4367 : cling::LookupHelper::NoDiagnostics);
4368 }
4369 return nullptr != decl;
4370}
4371
4372////////////////////////////////////////////////////////////////////////////////
4373/// Create list of pointers to base class(es) for TClass cl.
4374
4376{
4378 if (cl->fBase) {
4379 return;
4380 }
4382 if (!tci) return;
4384 TList *listOfBase = new TList;
4385 while (t.Next()) {
4386 // if name cannot be obtained no use to put in list
4387 if (t.IsValid() && t.Name()) {
4389 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4390 }
4391 }
4392 // Now that is complete, publish it.
4393 cl->fBase = listOfBase;
4394}
4395
4396////////////////////////////////////////////////////////////////////////////////
4397/// Create list of pointers to enums for TClass cl.
4398
4399void TCling::LoadEnums(TListOfEnums& enumList) const
4400{
4402
4403 const Decl * D;
4404 TClass* cl = enumList.GetClass();
4405 if (cl) {
4406 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4407 }
4408 else {
4409 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4410 }
4411 // Iterate on the decl of the class and get the enums.
4412 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4413 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4414 // Collect all contexts of the namespace.
4415 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4416 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4417 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4418 declIter != declEnd; ++declIter) {
4419 // Iterate on all decls for each context.
4420 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4421 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4422 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4423 // Get name of the enum type.
4424 std::string buf;
4425 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4426 llvm::raw_string_ostream stream(buf);
4427 // Don't trigger fopen of the source file to count lines:
4428 Policy.AnonymousTagLocations = false;
4429 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4430 stream.flush();
4431 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4432 if (!buf.empty()) {
4433 const char* name = buf.c_str();
4434 // Add the enum to the list of loaded enums.
4435 enumList.Get(ED, name);
4436 }
4437 }
4438 }
4439 }
4440 }
4441}
4442
4443////////////////////////////////////////////////////////////////////////////////
4444/// Create list of pointers to function templates for TClass cl.
4445
4447{
4449
4450 const Decl * D;
4451 TListOfFunctionTemplates* funcTempList;
4452 if (cl) {
4453 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4454 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4455 }
4456 else {
4457 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4458 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4459 }
4460 // Iterate on the decl of the class and get the enums.
4461 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4462 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4463 // Collect all contexts of the namespace.
4464 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4465 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4466 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4467 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4468 // Iterate on all decls for each context.
4469 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4470 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4471 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4472 funcTempList->Get(FTD);
4473 }
4474 }
4475 }
4476 }
4477}
4478
4479////////////////////////////////////////////////////////////////////////////////
4480/// Get the scopes representing using declarations of namespace
4481
4482std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4483{
4485 return ci->GetUsingNamespaces();
4486}
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Create list of pointers to data members for TClass cl.
4490/// This is now a nop. The creation and updating is handled in
4491/// TListOfDataMembers.
4492
4494{
4495}
4496
4497////////////////////////////////////////////////////////////////////////////////
4498/// Create list of pointers to methods for TClass cl.
4499/// This is now a nop. The creation and updating is handled in
4500/// TListOfFunctions.
4501
4503{
4504}
4505
4506////////////////////////////////////////////////////////////////////////////////
4507/// Update the list of pointers to method for TClass cl
4508/// This is now a nop. The creation and updating is handled in
4509/// TListOfFunctions.
4510
4512{
4513}
4514
4515////////////////////////////////////////////////////////////////////////////////
4516/// Update the list of pointers to data members for TClass cl
4517/// This is now a nop. The creation and updating is handled in
4518/// TListOfDataMembers.
4519
4521{
4522}
4523
4524////////////////////////////////////////////////////////////////////////////////
4525/// Create list of pointers to method arguments for TMethod m.
4526
4528{
4530 if (m->fMethodArgs) {
4531 return;
4532 }
4533 TList *arglist = new TList;
4535 while (t.Next()) {
4536 if (t.IsValid()) {
4538 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4539 }
4540 }
4541 m->fMethodArgs = arglist;
4542}
4543
4544////////////////////////////////////////////////////////////////////////////////
4545/// Return whether we are waiting for more input either because the collected
4546/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4547
4549{
4550 return fMetaProcessor->awaitingMoreInput();
4551}
4552
4553////////////////////////////////////////////////////////////////////////////////
4554/// Generate a TClass for the given class.
4555/// Since the caller has already check the ClassInfo, let it give use the
4556/// result (via the value of emulation) rather than recalculate it.
4557
4558TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4559{
4560// For now the following line would lead to the (unwanted) instantiation
4561// of class template. This could/would need to be resurrected only if
4562// we re-introduce so sort of automatic instantiation. However this would
4563// have to include carefull look at the template parameter to avoid
4564// creating instance we can not really use (if the parameter are only forward
4565// declaration or do not have all the necessary interfaces).
4566
4567 // TClingClassInfo tci(fInterpreter, classname);
4568 // if (1 || !tci.IsValid()) {
4569
4570 Version_t version = 1;
4571 if (TClassEdit::IsSTLCont(classname)) {
4572 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4573 }
4575 TClass *cl = new TClass(classname, version, silent);
4576 if (!emulation) {
4577 // Set the class version if the class is versioned.
4578 // Note that we cannot just call CLASS::Class_Version() as we might not have
4579 // an execution engine (when invoked from rootcling).
4580
4581 // Do not call cl->GetClassVersion(), it has side effects!
4582 Version_t oldvers = cl->fClassVersion;
4583 if (oldvers == version && cl->GetClassInfo()) {
4584 // We have a version and it might need an update.
4586 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4587 // Namespaces don't have class versions.
4588 return cl;
4589 }
4590 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4593 if (!mi.IsValid()) {
4594 if (cl->TestBit(TClass::kIsTObject)) {
4595 Error("GenerateTClass",
4596 "Cannot find %s::Class_Version()! Class version might be wrong.",
4597 cl->GetName());
4598 }
4599 return cl;
4600 }
4601 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4602 *fInterpreter);
4603 if (newvers == -1) {
4604 // Didn't manage to determine the class version from the AST.
4605 // Use runtime instead.
4606 if ((mi.Property() & kIsStatic)
4607 && !fInterpreter->isInSyntaxOnlyMode()) {
4608 // This better be a static function.
4610 callfunc.SetFunc(&mi);
4611 newvers = callfunc.ExecInt(nullptr);
4612 } else {
4613 Error("GenerateTClass",
4614 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4615 cl->GetName());
4616 }
4617 }
4618 if (newvers != oldvers) {
4619 cl->fClassVersion = newvers;
4620 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4621 }
4622 }
4623 }
4624
4625 return cl;
4626
4627// } else {
4628// return GenerateTClass(&tci,silent);
4629// }
4630}
4631
4632#if 0
4633////////////////////////////////////////////////////////////////////////////////
4634
4635static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4636{
4637 includes += info->FileName();
4638
4639 const clang::ClassTemplateSpecializationDecl *templateCl
4640 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4641 if (templateCl) {
4642 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4643 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4644 if (arg.getKind() == clang::TemplateArgument::Type) {
4645 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4646
4647 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4648 // We really need a header file.
4649 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4650 if (argdecl) {
4651 includes += ";";
4652 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4653 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4654 } else {
4655 std::string Result;
4656 llvm::raw_string_ostream OS(Result);
4657 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4658 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4659 }
4660 }
4661 }
4662 }
4663 }
4664}
4665#endif
4666
4667////////////////////////////////////////////////////////////////////////////////
4668/// Generate a TClass for the given class.
4669
4670TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4671{
4672 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4673 if (!info || !info->IsValid()) {
4674 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4675 return nullptr;
4676 }
4677 // We are in the case where we have AST nodes for this class.
4678 TClass *cl = nullptr;
4679 std::string classname;
4680 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4681 if (TClassEdit::IsSTLCont(classname)) {
4682#if 0
4683 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4684 // We need to build up the list of required headers, by
4685 // looking at each template arguments.
4686 TString includes;
4687 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4688
4689 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4690 // 0 means success.
4691 cl = TClass::LoadClass(classnam.c_str(), silent);
4692 if (cl == 0) {
4693 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4694 }
4695 }
4696#endif
4697 if (cl == nullptr) {
4698 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4699 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4700 }
4701 } else {
4702 // For regular class, just create a TClass on the fly ...
4703 // Not quite useful yet, but that what CINT used to do anyway.
4704 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4705 }
4706 // Add the new TClass to the map of declid and TClass*.
4707 if (cl) {
4709 }
4710 return cl;
4711}
4712
4713////////////////////////////////////////////////////////////////////////////////
4714/// Generate the dictionary for the C++ classes listed in the first
4715/// argument (in a semi-colon separated list).
4716/// 'includes' contains a semi-colon separated list of file to
4717/// `#include` in the dictionary.
4718/// For example:
4719/// ~~~ {.cpp}
4720/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4721/// ~~~
4722/// or
4723/// ~~~ {.cpp}
4724/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4725/// ~~~
4726
4727Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4728{
4729 if (classes == nullptr || classes[0] == 0) {
4730 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4731 return 0;
4732 }
4733 // Split the input list
4734 std::vector<std::string> listClasses;
4735 for (
4736 const char* current = classes, *prev = classes;
4737 *current != 0;
4738 ++current
4739 ) {
4740 if (*current == ';') {
4741 listClasses.push_back(std::string(prev, current - prev));
4742 prev = current + 1;
4743 }
4744 else if (*(current + 1) == 0) {
4745 listClasses.push_back(std::string(prev, current + 1 - prev));
4746 prev = current + 1;
4747 }
4748 }
4749 std::vector<std::string> listIncludes;
4750 if (!includes)
4751 includes = "";
4752 for (
4753 const char* current = includes, *prev = includes;
4754 *current != 0;
4755 ++current
4756 ) {
4757 if (*current == ';') {
4758 listIncludes.push_back(std::string(prev, current - prev));
4759 prev = current + 1;
4760 }
4761 else if (*(current + 1) == 0) {
4762 listIncludes.push_back(std::string(prev, current + 1 - prev));
4763 prev = current + 1;
4764 }
4765 }
4766 // Generate the temporary dictionary file
4767 return !TCling_GenerateDictionary(listClasses, listIncludes,
4768 std::vector<std::string>(), std::vector<std::string>());
4769}
4770
4771////////////////////////////////////////////////////////////////////////////////
4772/// Return pointer to cling Decl of global/static variable that is located
4773/// at the address given by addr.
4774
4775TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4776{
4778 DeclId_t d;
4779 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4780
4781 // Could trigger deserialization of decls.
4782 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4783
4784 if (cl) {
4785 d = cl->GetDataMember(name);
4786 // We check if the decl of the data member has an annotation which indicates
4787 // an ioname.
4788 // In case this is true, if the name requested is not the ioname, we
4789 // return 0, as if the member did not exist. In some sense we override
4790 // the information in the TClassInfo instance, isolating the typesystem in
4791 // TClass from the one in the AST.
4792 if (const ValueDecl* decl = (const ValueDecl*) d){
4793 std::string ioName;
4794 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4795 if (hasIoName && ioName != name) return nullptr;
4796 }
4797 return d;
4798 }
4799 // We are looking up for something on the TU scope.
4800 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4801 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4802 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4803 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4804 // are only fulfilling ROOT's understanding for a Data Member.
4805 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4806 // similar as below.
4807 using namespace clang;
4808 Sema& SemaR = fInterpreter->getSema();
4809 DeclarationName DName = &SemaR.Context.Idents.get(name);
4810
4811 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4812 Sema::ForExternalRedeclaration);
4813
4814 cling::utils::Lookup::Named(&SemaR, R);
4815
4816 LookupResult::Filter F = R.makeFilter();
4817 // Filter the data-member looking decls.
4818 while (F.hasNext()) {
4819 NamedDecl *D = F.next();
4820 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4821 isa<IndirectFieldDecl>(D))
4822 continue;
4823 F.erase();
4824 }
4825 F.done();
4826
4827 if (R.isSingleResult())
4828 return R.getFoundDecl();
4829 return nullptr;
4830}
4831
4832////////////////////////////////////////////////////////////////////////////////
4833/// Return pointer to cling Decl of global/static variable that is located
4834/// at the address given by addr.
4835
4837{
4839
4840 const clang::Decl* possibleEnum = nullptr;
4841 // FInd the context of the decl.
4842 if (cl) {
4844 if (cci) {
4845 const clang::DeclContext* dc = nullptr;
4846 if (const clang::Decl* D = cci->GetDecl()) {
4847 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4848 dc = dyn_cast<clang::RecordDecl>(D);
4849 }
4850 }
4851 if (dc) {
4852 // If it is a data member enum.
4853 // Could trigger deserialization of decls.
4854 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4855 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4856 } else {
4857 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4858 }
4859 }
4860 } else {
4861 // If it is a global enum.
4862 // Could trigger deserialization of decls.
4863 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4864 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4865 }
4866 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4867 && isa<clang::EnumDecl>(possibleEnum)) {
4868 return possibleEnum;
4869 }
4870 return nullptr;
4871}
4872
4873////////////////////////////////////////////////////////////////////////////////
4874/// Return pointer to cling DeclId for a global value
4875
4876TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4877{
4878 if (!gv) return nullptr;
4879
4880 llvm::StringRef mangled_name = gv->getName();
4881
4882 int err = 0;
4883 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4884 if (err) {
4885 if (err == -2) {
4886 // It might simply be an unmangled global name.
4887 DeclId_t d;
4889 d = gcl.GetDataMember(mangled_name.str().c_str());
4890 return d;
4891 }
4892 return nullptr;
4893 }
4894
4895 std::string scopename(demangled_name_c);
4896 free(demangled_name_c);
4897
4898 //
4899 // Separate out the class or namespace part of the
4900 // function name.
4901 //
4902 std::string dataname;
4903
4904 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4905 scopename.erase(0, sizeof("typeinfo for ")-1);
4906 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4907 scopename.erase(0, sizeof("vtable for ")-1);
4908 } else {
4909 // See if it is a function
4910 std::string::size_type pos = scopename.rfind('(');
4911 if (pos != std::string::npos) {
4912 return nullptr;
4913 }
4914 // Separate the scope and member name
4915 pos = scopename.rfind(':');
4916 if (pos != std::string::npos) {
4917 if ((pos != 0) && (scopename[pos-1] == ':')) {
4918 dataname = scopename.substr(pos+1);
4919 scopename.erase(pos-1);
4920 }
4921 } else {
4922 scopename.clear();
4923 dataname = scopename;
4924 }
4925 }
4926 //fprintf(stderr, "name: '%s'\n", name.c_str());
4927 // Now we have the class or namespace name, so do the lookup.
4928
4929
4930 DeclId_t d;
4931 if (scopename.size()) {
4932 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4933 d = cl.GetDataMember(dataname.c_str());
4934 }
4935 else {
4937 d = gcl.GetDataMember(dataname.c_str());
4938 }
4939 return d;
4940}
4941
4942////////////////////////////////////////////////////////////////////////////////
4943/// NOT IMPLEMENTED.
4944
4946{
4947 Error("GetDataMemberWithValue()", "not implemented");
4948 return nullptr;
4949}
4950
4951////////////////////////////////////////////////////////////////////////////////
4952/// Return pointer to cling DeclId for a data member with a given name.
4953
4955{
4956 // NOT IMPLEMENTED.
4957 Error("GetDataMemberAtAddr()", "not implemented");
4958 return nullptr;
4959}
4960
4961////////////////////////////////////////////////////////////////////////////////
4962/// Return the cling mangled name for a method of a class with parameters
4963/// params (params is a string of actual arguments, not formal ones). If the
4964/// class is 0 the global function list will be searched.
4965
4966TString TCling::GetMangledName(TClass* cl, const char* method,
4967 const char* params, Bool_t objectIsConst /* = kFALSE */)
4968{
4971 if (cl) {
4973 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4974 &offset);
4975 }
4976 else {
4979 func.SetFunc(&gcl, method, params, &offset);
4980 }
4982 if (!mi) return "";
4983 TString mangled_name( mi->GetMangledName() );
4984 delete mi;
4985 return mangled_name;
4986}
4987
4988////////////////////////////////////////////////////////////////////////////////
4989/// Return the cling mangled name for a method of a class with a certain
4990/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4991/// list will be searched.
4992
4994 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4995 EFunctionMatchMode mode /* = kConversionMatch */)
4996{
4998 if (cl) {
4999 return ((TClingClassInfo*)cl->GetClassInfo())->
5000 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5001 }
5003 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5004}
5005
5006////////////////////////////////////////////////////////////////////////////////
5007/// Return pointer to cling interface function for a method of a class with
5008/// parameters params (params is a string of actual arguments, not formal
5009/// ones). If the class is 0 the global function list will be searched.
5010
5011void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5012 const char* params, Bool_t objectIsConst /* = kFALSE */)
5013{
5016 if (cl) {
5018 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5019 &offset);
5020 }
5021 else {
5024 func.SetFunc(&gcl, method, params, &offset);
5025 }
5026 return (void*) func.InterfaceMethod();
5027}
5028
5029////////////////////////////////////////////////////////////////////////////////
5030/// Return pointer to cling interface function for a method of a class with
5031/// a certain name.
5032
5033TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5034{
5036 DeclId_t f;
5037 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5038 if (cl) {
5039 f = cl->GetMethod(method).GetDeclId();
5040 }
5041 else {
5043 f = gcl.GetMethod(method).GetDeclId();
5044 }
5045 return f;
5046
5047}
5048
5049////////////////////////////////////////////////////////////////////////////////
5050/// Insert overloads of name in cl to res.
5051
5052void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5053 std::vector<DeclId_t>& res) const
5054{
5055 clang::Sema& S = fInterpreter->getSema();
5056 clang::ASTContext& Ctx = S.Context;
5057 const clang::Decl* CtxDecl
5058 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5059 Ctx.getTranslationUnitDecl();
5060 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5061 const clang::DeclContext* DeclCtx = RecDecl;
5062
5063 if (!DeclCtx)
5064 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5065 if (!DeclCtx) return;
5066
5067 clang::DeclarationName DName;
5068 // The DeclarationName is funcname, unless it's a ctor or dtor.
5069 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5070
5071 if (RecDecl) {
5072 if (RecDecl->getNameAsString() == funcname) {
5073 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5074 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5075 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5076 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5077 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5078 } else {
5079 DName = &Ctx.Idents.get(funcname);
5080 }
5081 } else {
5082 DName = &Ctx.Idents.get(funcname);
5083 }
5084
5085 // NotForRedeclaration: we want to find names in inline namespaces etc.
5086 clang::LookupResult R(S, DName, clang::SourceLocation(),
5087 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5088 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5089 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5090 if (R.empty()) return;
5091 R.resolveKind();
5092 res.reserve(res.size() + (R.end() - R.begin()));
5093 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5094 IR != ER; ++IR) {
5095 if (const clang::FunctionDecl* FD
5096 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5097 if (!FD->getDescribedFunctionTemplate()) {
5098 res.push_back(FD);
5099 }
5100 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5101 // FIXME: multi-level using
5102 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5103 res.push_back(USD);
5104 }
5105 }
5106 }
5107}
5108
5109////////////////////////////////////////////////////////////////////////////////
5110/// Return pointer to cling interface function for a method of a class with
5111/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5112/// function list will be searched.
5113
5115 const char* proto,
5116 Bool_t objectIsConst /* = kFALSE */,
5117 EFunctionMatchMode mode /* = kConversionMatch */)
5118{
5120 void* f;
5121 if (cl) {
5122 f = ((TClingClassInfo*)cl->GetClassInfo())->
5123 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5124 }
5125 else {
5127 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5128 }
5129 return f;
5130}
5131
5132////////////////////////////////////////////////////////////////////////////////
5133/// Return pointer to cling DeclId for a method of a class with
5134/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5135/// function list will be searched.
5136
5137TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5138 const char* params,
5139 Bool_t objectIsConst /* = kFALSE */)
5140{
5142 DeclId_t f;
5143 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5144 if (cl) {
5145 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5146 }
5147 else {
5149 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5150 }
5151 return f;
5152}
5153
5154////////////////////////////////////////////////////////////////////////////////
5155/// Return pointer to cling interface function for a method of a class with
5156/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5157/// function list will be searched.
5158
5159TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5160 const char* proto,
5161 Bool_t objectIsConst /* = kFALSE */,
5162 EFunctionMatchMode mode /* = kConversionMatch */)
5163{
5165 DeclId_t f;
5166 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5167 if (cl) {
5168 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5169 }
5170 else {
5172 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5173 }
5174 return f;
5175}
5176
5177////////////////////////////////////////////////////////////////////////////////
5178/// Return pointer to cling interface function for a method of a class with
5179/// a certain name.
5180
5181TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5182{
5184 DeclId_t f;
5185 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5186 if (cl) {
5187 f = cl->GetFunctionTemplate(name);
5188 }
5189 else {
5191 f = gcl.GetFunctionTemplate(name);
5192 }
5193 return f;
5194
5195}
5196
5197////////////////////////////////////////////////////////////////////////////////
5198/// The 'name' is known to the interpreter, this function returns
5199/// the internal version of this name (usually just resolving typedefs)
5200/// This is used in particular to synchronize between the name used
5201/// by rootcling and by the run-time environment (TClass)
5202/// Return 0 if the name is not known.
5203
5204void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5205{
5206 output.clear();
5207
5209
5211 if (!cl.IsValid()) {
5212 return ;
5213 }
5214 if (full) {
5216 return;
5217 }
5218 // Well well well, for backward compatibility we need to act a bit too
5219 // much like CINT.
5222
5223 return;
5224}
5225
5226////////////////////////////////////////////////////////////////////////////////
5227/// Execute a global function with arguments params.
5228///
5229/// FIXME: The cint-based version of this code does not check if the
5230/// SetFunc() call works, and does not do any real checking
5231/// for errors from the Exec() call. It did fetch the most
5232/// recent cint security error and return that in error, but
5233/// this does not really translate well to cling/clang. We
5234/// should enhance these interfaces so that we can report
5235/// compilation and runtime errors properly.
5236
5237void TCling::Execute(const char* function, const char* params, int* error)
5238{
5240 if (error) {
5241 *error = TInterpreter::kNoError;
5242 }
5244 Longptr_t offset = 0L;
5246 func.SetFunc(&cl, function, params, &offset);
5247 func.Exec(nullptr);
5248}
5249
5250////////////////////////////////////////////////////////////////////////////////
5251/// Execute a method from class cl with arguments params.
5252///
5253/// FIXME: The cint-based version of this code does not check if the
5254/// SetFunc() call works, and does not do any real checking
5255/// for errors from the Exec() call. It did fetch the most
5256/// recent cint security error and return that in error, but
5257/// this does not really translate well to cling/clang. We
5258/// should enhance these interfaces so that we can report
5259/// compilation and runtime errors properly.
5260
5261void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5262 const char* params, Bool_t objectIsConst, int* error)
5263{
5265 if (error) {
5266 *error = TInterpreter::kNoError;
5267 }
5268 // If the actual class of this object inherits 2nd (or more) from TObject,
5269 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5270 // hence gInterpreter->Execute will improperly correct the offset.
5271 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5272 Longptr_t offset = 0L;
5274 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5275 void* address = (void*)((Longptr_t)addr + offset);
5276 func.Exec(address);
5277}
5278
5279////////////////////////////////////////////////////////////////////////////////
5280
5281void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5282 const char* params, int* error)
5283{
5284 Execute(obj,cl,method,params,false,error);
5285}
5286
5287////////////////////////////////////////////////////////////////////////////////
5288/// Execute a method from class cl with the arguments in array params
5289/// (params[0] ... params[n] = array of TObjString parameters).
5290/// Convert the TObjArray array of TObjString parameters to a character
5291/// string of comma separated parameters.
5292/// The parameters of type 'char' are enclosed in double quotes and all
5293/// internal quotes are escaped.
5294
5295void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5296 TObjArray* params, int* error)
5297{
5298 if (!method) {
5299 Error("Execute", "No method was defined");
5300 return;
5301 }
5302 TList* argList = method->GetListOfMethodArgs();
5303 // Check number of actual parameters against of expected formal ones
5304
5305 Int_t nparms = argList->LastIndex() + 1;
5306 Int_t argc = params ? params->GetEntries() : 0;
5307
5308 if (argc > nparms) {
5309 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5310 return;
5311 }
5312 if (nparms != argc) {
5313 // Let's see if the 'missing' argument are all defaulted.
5314 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5315 assert(nparms > 0);
5316
5317 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5318 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5319 // There is a default value for the first missing
5320 // argument, so we are fine.
5321 } else {
5322 Int_t firstDefault = -1;
5323 for (Int_t i = 0; i < nparms; i ++) {
5324 arg = (TMethodArg *) argList->At( i );
5325 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5326 firstDefault = i;
5327 break;
5328 }
5329 }
5330 if (firstDefault >= 0) {
5331 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);
5332 } else {
5333 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5334 }
5335 return;
5336 }
5337 }
5338
5339 const char* listpar = "";
5340 TString complete(10);
5341 if (params) {
5342 // Create a character string of parameters from TObjArray
5343 TIter next(params);
5344 for (Int_t i = 0; i < argc; i ++) {
5345 TMethodArg* arg = (TMethodArg*) argList->At(i);
5347 TObjString* nxtpar = (TObjString*) next();
5348 if (i) {
5349 complete += ',';
5350 }
5351 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5352 TString chpar('\"');
5353 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5354 // At this point we have to check if string contains \\"
5355 // and apply some more sophisticated parser. Not implemented yet!
5356 complete += chpar;
5357 complete += '\"';
5358 }
5359 else {
5360 complete += nxtpar->String();
5361 }
5362 }
5363 listpar = complete.Data();
5364 }
5365
5366 // And now execute it.
5368 if (error) {
5369 *error = TInterpreter::kNoError;
5370 }
5371 // If the actual class of this object inherits 2nd (or more) from TObject,
5372 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5373 // hence gInterpreter->Execute will improperly correct the offset.
5374 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5376 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5377 func.Init(*minfo);
5378 func.SetArgs(listpar);
5379 // Now calculate the 'this' pointer offset for the method
5380 // when starting from the class described by cl.
5381 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5382 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5383 void* address = (void*)((Longptr_t)addr + offset);
5384 func.Exec(address);
5385}
5386
5387////////////////////////////////////////////////////////////////////////////////
5388
5389void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5390 const void* args[] /*=0*/,
5391 int nargs /*=0*/,
5392 void* ret/*= 0*/) const
5393{
5394 if (!method) {
5395 Error("ExecuteWithArgsAndReturn", "No method was defined");
5396 return;
5397 }
5398
5399 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5400 TClingCallFunc func(*minfo);
5401 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5402}
5403
5404////////////////////////////////////////////////////////////////////////////////
5405/// Execute a cling macro.
5406
5408{
5410 fCurExecutingMacros.push_back(filename);
5412 fCurExecutingMacros.pop_back();
5413 return result;
5414}
5415
5416////////////////////////////////////////////////////////////////////////////////
5417/// Return the file name of the current un-included interpreted file.
5418/// See the documentation for GetCurrentMacroName().
5419
5421{
5422 Warning("GetTopLevelMacroName", "Must change return type!");
5423 return fCurExecutingMacros.back();
5424}
5425
5426////////////////////////////////////////////////////////////////////////////////
5427/// Return the file name of the currently interpreted file,
5428/// included or not. Example to illustrate the difference between
5429/// GetCurrentMacroName() and GetTopLevelMacroName():
5430/// ~~~ {.cpp}
5431/// void inclfile() {
5432/// std::cout << "In inclfile.C" << std::endl;
5433/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5434/// TCling::GetCurrentMacroName() << std::endl;
5435/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5436/// TCling::GetTopLevelMacroName() << std::endl;
5437/// }
5438/// ~~~
5439/// ~~~ {.cpp}
5440/// void mymacro() {
5441/// std::cout << "In mymacro.C" << std::endl;
5442/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5443/// TCling::GetCurrentMacroName() << std::endl;
5444/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5445/// TCling::GetTopLevelMacroName() << std::endl;
5446/// std::cout << " Now calling inclfile..." << std::endl;
5447/// gInterpreter->ProcessLine(".x inclfile.C");;
5448/// }
5449/// ~~~
5450/// Running mymacro.C will print:
5451///
5452/// ~~~ {.cpp}
5453/// root [0] .x mymacro.C
5454/// ~~~
5455/// In mymacro.C
5456/// ~~~ {.cpp}
5457/// TCling::GetCurrentMacroName() returns ./mymacro.C
5458/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5459/// ~~~
5460/// Now calling inclfile...
5461/// In inclfile.h
5462/// ~~~ {.cpp}
5463/// TCling::GetCurrentMacroName() returns inclfile.C
5464/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5465/// ~~~
5466
5468{
5469#if defined(R__MUST_REVISIT)
5470#if R__MUST_REVISIT(6,0)
5471 Warning("GetCurrentMacroName", "Must change return type!");
5472#endif
5473#endif
5474 return fCurExecutingMacros.back();
5475}
5476
5477////////////////////////////////////////////////////////////////////////////////
5478/// Return the absolute type of typeDesc.
5479/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5480/// You need to use the result immediately before it is being overwritten.
5481
5482const char* TCling::TypeName(const char* typeDesc)
5483{
5484 TTHREAD_TLS_DECL(std::string,t);
5485
5486 if (!strstr(typeDesc, "(*)(")) {
5487 const char *s = strchr(typeDesc, ' ');
5488 const char *template_start = strchr(typeDesc, '<');
5489 if (!strcmp(typeDesc, "long long")) {
5490 t = typeDesc;
5491 }
5492 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5493 t = typeDesc;
5494 }
5495 // s is the position of the second 'word' (if any)
5496 // except in the case of templates where there will be a space
5497 // just before any closing '>': eg.
5498 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5499 else if (s && (template_start == nullptr || (s < template_start))) {
5500 t = s + 1;
5501 }
5502 else {
5503 t = typeDesc;
5504 }
5505 }
5506 else {
5507 t = typeDesc;
5508 }
5509 auto l = t.length();
5510 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5511 --l;
5512 t.resize(l);
5513 return t.c_str(); // NOLINT
5514}
5515
5516static bool requiresRootMap(const char* rootmapfile)
5517{
5518 assert(rootmapfile && *rootmapfile);
5519
5520 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5521 libName.consume_back(".rootmap");
5522
5523 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5524}
5525
5526////////////////////////////////////////////////////////////////////////////////
5527/// Read and parse a rootmapfile in its new format, and return 0 in case of
5528/// success, -1 if the file has already been read, and -3 in case its format
5529/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5530/// error.
5531
5532int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5533{
5534 if (!(rootmapfile && *rootmapfile))
5535 return 0;
5536
5537 if (!requiresRootMap(rootmapfile))
5538 return 0; // success
5539
5540 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5541 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5542
5543 std::string rootmapfileNoBackslash(rootmapfile);
5544#ifdef _MSC_VER
5545 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5546#endif
5547 // Add content of a specific rootmap file
5548 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5549 return -1;
5550
5551 // Line 1 is `{ decls }`
5552 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5553
5554 std::ifstream file(rootmapfileNoBackslash);
5555 std::string line;
5556 line.reserve(200);
5557 std::string lib_name;
5558 line.reserve(100);
5559 bool newFormat = false;
5560 while (getline(file, line, '\n')) {
5561 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5562 file.close();
5563 return -3; // old format
5564 }
5565 newFormat = true;
5566
5567 if (line.compare(0, 9, "{ decls }") == 0) {
5568 // forward declarations
5569
5570 while (getline(file, line, '\n')) {
5571 if (line[0] == '[')
5572 break;
5573 if (!uniqueString) {
5574 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5575 rootmapfileNoBackslash.c_str());
5576 return -4;
5577 }
5578 if (!lineDirective.empty())
5579 uniqueString->Append(lineDirective);
5580 uniqueString->Append(line + '\n');
5581 }
5582 }
5583 const char firstChar = line[0];
5584 if (firstChar == '[') {
5585 // new section (library)
5586 auto brpos = line.find(']');
5587 if (brpos == string::npos)
5588 continue;
5589 lib_name = line.substr(1, brpos - 1);
5590 // Remove spaces at the beginning and at the end of the library name
5591 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5592 lib_name.erase(0, lib_name.find_first_not_of(' '));
5593 if (gDebug > 3) {
5594 TString lib_nameTstr(lib_name.c_str());
5595 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5596 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5597 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5598 if (wlib) {
5599 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5600 } else {
5601 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5602 }
5603 delete[] wlib;
5604 delete tokens;
5605 }
5606 } else {
5607 auto keyLenIt = keyLenMap.find(firstChar);
5608 if (keyLenIt == keyLenMap.end())
5609 continue;
5610 unsigned int keyLen = keyLenIt->second;
5611 // Do not make a copy, just start after the key
5612 const char *keyname = line.c_str() + keyLen;
5613 if (gDebug > 6)
5614 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5615 TEnvRec *isThere = fMapfile->Lookup(keyname);
5616 if (isThere) {
5617 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5618 if (firstChar == 'n') {
5619 if (gDebug > 3)
5620 Info("ReadRootmapFile",
5621 "While processing %s, namespace %s was found to be associated to %s although it is already "
5622 "associated to %s",
5623 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5624 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5625 lib_name += " ";
5626 lib_name += isThere->GetValue();
5627 fMapfile->SetValue(keyname, lib_name.c_str());
5628 } else if (!TClassEdit::IsSTLCont(keyname)) {
5629 Warning("ReadRootmapFile",
5630 "While processing %s, %s %s was found to be associated to %s although it is already "
5631 "associated to %s",
5632 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5633 isThere->GetValue());
5634 }
5635 } else { // the same key for the same lib
5636 if (gDebug > 3)
5637 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5638 rootmapfile, keyname, lib_name.c_str());
5639 }
5640 } else {
5641 fMapfile->SetValue(keyname, lib_name.c_str());
5642 }
5643 }
5644 }
5645 file.close();
5646 return 0;
5647}
5648
5649////////////////////////////////////////////////////////////////////////////////
5650/// Create a resource table and read the (possibly) three resource files,
5651/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5652/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5653/// can read additional user defined resource files by creating additional TEnv
5654/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5655/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5656/// case the home directory resides on an automounted remote file system
5657/// and one wants to avoid the file system from being mounted.
5658
5660{
5661 assert(requiresRootMap(name) && "We have a module!");
5662
5663 if (!requiresRootMap(name))
5664 return;
5665
5666 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5667
5668 fMapfile->SetRcName(name);
5669
5670 TString sname = "system";
5671 sname += name;
5672 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5673
5674 Int_t ret = ReadRootmapFile(s);
5675 if (ret == -3) // old format
5676 fMapfile->ReadFile(s, kEnvGlobal);
5677 delete [] s;
5678 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5679 s = gSystem->ConcatFileName(gSystem->HomeDirectory(), name);
5680 ret = ReadRootmapFile(s);
5681 if (ret == -3) // old format
5682 fMapfile->ReadFile(s, kEnvUser);
5683 delete [] s;
5684 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5685 ret = ReadRootmapFile(name);
5686 if (ret == -3) // old format
5687 fMapfile->ReadFile(name, kEnvLocal);
5688 }
5689 } else {
5690 ret = ReadRootmapFile(name);
5691 if (ret == -3) // old format
5692 fMapfile->ReadFile(name, kEnvLocal);
5693 }
5694 fMapfile->IgnoreDuplicates(ignore);
5695}
5696
5697
5698namespace {
5699 using namespace clang;
5700
5701 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5702 // This class is to be considered an helper for AutoLoading.
5703 // It is a recursive visitor is used to inspect namespaces and specializations
5704 // coming from forward declarations in rootmaps and to set the external visible
5705 // storage flag for them.
5706 public:
5707 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5708 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5709 // We want to enable the external lookup for this namespace
5710 // because it may shadow the lookup of other names contained
5711 // in that namespace
5712
5713 nsDecl->setHasExternalVisibleStorage();
5714 fNSSet.insert(nsDecl);
5715 return true;
5716 }
5717 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5718 // We want to enable the external lookup for this specialization
5719 // because we can provide a definition for it!
5720 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5721 //SpecSet.insert(specDecl);
5722 specDecl->setHasExternalLexicalStorage();
5723
5724 // No need to recurse. On the contrary, recursing is actively harmful:
5725 // NOTE: must not recurse to prevent this visitor from triggering loading from
5726 // the external AST source (i.e. autoloading). This would be triggered right here,
5727 // before autoloading is even set up, as rootmap file parsing happens before that.
5728 // Even if autoloading is off and has no effect, triggering loading from external
5729 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5730 // from subsequent autoloads!
5731 return false;
5732 }
5733 private:
5734 std::unordered_set<const NamespaceDecl*>& fNSSet;
5735 };
5736}
5737
5738////////////////////////////////////////////////////////////////////////////////
5739/// Load map between class and library. If rootmapfile is specified a
5740/// specific rootmap file can be added (typically used by ACLiC).
5741/// In case of error -1 is returned, 0 otherwise.
5742/// The interpreter uses this information to automatically load the shared
5743/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5744
5745Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5746{
5747 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5748 return 0;
5749
5751
5752 // open the [system].rootmap files
5753 if (!fMapfile) {
5754 fMapfile = new TEnv();
5755 fMapfile->IgnoreDuplicates(kTRUE);
5757 fRootmapFiles->SetOwner();
5758 InitRootmapFile(".rootmap");
5759 }
5760
5761 // Prepare a list of all forward declarations for cling
5762 // For some experiments it is easily as big as 500k characters. To be on the
5763 // safe side, we go for 1M.
5764 TUniqueString uniqueString(1048576);
5765
5766 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5767 // A rootmap file must end with the string ".rootmap".
5768 TString ldpath = gSystem->GetDynamicPath();
5769 if (ldpath != fRootmapLoadPath) {
5770 fRootmapLoadPath = ldpath;
5771#ifdef WIN32
5772 TObjArray* paths = ldpath.Tokenize(";");
5773#else
5774 TObjArray* paths = ldpath.Tokenize(":");
5775#endif
5776 TString d;
5777 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5778 d = ((TObjString *)paths->At(i))->GetString();
5779 // check if directory already scanned
5780 Int_t skip = 0;
5781 for (Int_t j = 0; j < i; j++) {
5782 TString pd = ((TObjString *)paths->At(j))->GetString();
5783 if (pd == d) {
5784 skip++;
5785 break;
5786 }
5787 }
5788 if (!skip) {
5789 void* dirp = gSystem->OpenDirectory(d);
5790 if (dirp) {
5791 if (gDebug > 3) {
5792 Info("LoadLibraryMap", "%s", d.Data());
5793 }
5794 const char* f1;
5795 while ((f1 = gSystem->GetDirEntry(dirp))) {
5796 TString f = f1;
5797 if (f.EndsWith(".rootmap")) {
5798 TString p;
5799 p = d + "/" + f;
5800 if (!gSystem->AccessPathName(p, kReadPermission)) {
5801 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5802 if (gDebug > 4) {
5803 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5804 }
5805 Int_t ret = ReadRootmapFile(p, &uniqueString);
5806
5807 if (ret == 0)
5808 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5809 if (ret == -3) {
5810 // old format
5811 fMapfile->ReadFile(p, kEnvGlobal);
5812 fRootmapFiles->Add(new TNamed(f, p));
5813 }
5814 }
5815 // else {
5816 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5817 // fRootmapFiles->FindObject(f)->ls();
5818 // }
5819 }
5820 }
5821 if (f.BeginsWith("rootmap")) {
5822 TString p;
5823 p = d + "/" + f;
5824 FileStat_t stat;
5825 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5826 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5827 }
5828 }
5829 }
5830 }
5831 gSystem->FreeDirectory(dirp);
5832 }
5833 }
5834 delete paths;
5835 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5836 return -1;
5837 }
5838 }
5839 if (rootmapfile && *rootmapfile) {
5840 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5841 if (res == 0) {
5842 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5843 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5844 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5845 }
5846 else if (res == -3) {
5847 // old format
5848 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5849 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5850 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5851 fMapfile->IgnoreDuplicates(ignore);
5852 }
5853 }
5854 TEnvRec* rec;
5855 TIter next(fMapfile->GetTable());
5856 while ((rec = (TEnvRec*) next())) {
5857 TString cls = rec->GetName();
5858 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5859 // get the first lib from the list of lib and dependent libs
5860 TString libs = rec->GetValue();
5861 if (libs == "") {
5862 continue;
5863 }
5864 TString delim(" ");
5865 TObjArray* tokens = libs.Tokenize(delim);
5866 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5867 // convert "@@" to "::", we used "@@" because TEnv
5868 // considers "::" a terminator
5869 cls.Remove(0, 8);
5870 cls.ReplaceAll("@@", "::");
5871 // convert "-" to " ", since class names may have
5872 // blanks and TEnv considers a blank a terminator
5873 cls.ReplaceAll("-", " ");
5874 if (gDebug > 6) {
5875 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5876 if (wlib) {
5877 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5878 }
5879 else {
5880 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5881 }
5882 delete[] wlib;
5883 }
5884 delete tokens;
5885 }
5886 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5887 cls.Remove(0, 8);
5888 // convert "-" to " ", since class names may have
5889 // blanks and TEnv considers a blank a terminator
5890 cls.ReplaceAll("-", " ");
5891 fInterpreter->declare(cls.Data());
5892 }
5893 }
5894
5895 // Process the forward declarations collected
5896 cling::Transaction* T = nullptr;
5897 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5898 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5899
5900 if (compRes!=cling::Interpreter::kSuccess){
5901 Warning("LoadLibraryMap",
5902 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5903 }
5904
5905 if (T) {
5906 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5907 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5908 if (declIt->m_DGR.isSingleDecl()) {
5909 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5910 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5911 evsAdder.TraverseDecl(D);
5912 }
5913 }
5914 }
5915 }
5916 }
5917
5918 // clear duplicates
5919
5920 return 0;
5921}
5922
5923////////////////////////////////////////////////////////////////////////////////
5924/// Scan again along the dynamic path for library maps. Entries for the loaded
5925/// shared libraries are unloaded first. This can be useful after reseting
5926/// the dynamic path through TSystem::SetDynamicPath()
5927/// In case of error -1 is returned, 0 otherwise.
5928
5935
5936////////////////////////////////////////////////////////////////////////////////
5937/// Reload the library map entries coming from all the loaded shared libraries,
5938/// after first unloading the current ones.
5939/// In case of error -1 is returned, 0 otherwise.
5940
5942{
5943 const TString sharedLibLStr = GetSharedLibs();
5944 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5945 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5946 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5947 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5948 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5949 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5950 if (ret < 0) {
5951 continue;
5952 }
5953 TString rootMapBaseStr = sharedLibBaseStr;
5954 if (sharedLibBaseStr.EndsWith(".dll")) {
5955 rootMapBaseStr.ReplaceAll(".dll", "");
5956 }
5957 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5958 rootMapBaseStr.ReplaceAll(".DLL", "");
5959 }
5960 else if (sharedLibBaseStr.EndsWith(".so")) {
5961 rootMapBaseStr.ReplaceAll(".so", "");
5962 }
5963 else if (sharedLibBaseStr.EndsWith(".sl")) {
5964 rootMapBaseStr.ReplaceAll(".sl", "");
5965 }
5966 else if (sharedLibBaseStr.EndsWith(".dl")) {
5967 rootMapBaseStr.ReplaceAll(".dl", "");
5968 }
5969 else if (sharedLibBaseStr.EndsWith(".a")) {
5970 rootMapBaseStr.ReplaceAll(".a", "");
5971 }
5972 else {
5973 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5974 delete sharedLibL;
5975 return -1;
5976 }
5977 rootMapBaseStr += ".rootmap";
5978 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5979 if (!rootMap) {
5980 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5981 delete[] rootMap;
5982 delete sharedLibL;
5983 return -1;
5984 }
5985 const Int_t status = LoadLibraryMap(rootMap);
5986 if (status < 0) {
5987 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5988 delete[] rootMap;
5989 delete sharedLibL;
5990 return -1;
5991 }
5992 delete[] rootMap;
5993 }
5994 delete sharedLibL;
5995 return 0;
5996}
5997
5998////////////////////////////////////////////////////////////////////////////////
5999/// Unload the library map entries coming from all the loaded shared libraries.
6000/// Returns 0 if succesful
6001
6003{
6004 const TString sharedLibLStr = GetSharedLibs();
6005 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6006 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6007 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6008 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6009 UnloadLibraryMap(sharedLibBaseStr);
6010 }
6011 delete sharedLibL;
6012 return 0;
6013}
6014
6015////////////////////////////////////////////////////////////////////////////////
6016/// Unload library map entries coming from the specified library.
6017/// Returns -1 in case no entries for the specified library were found,
6018/// 0 otherwise.
6019
6021{
6022 if (!fMapfile || !library || !*library) {
6023 return 0;
6024 }
6025 TString libname(library);
6026 Ssiz_t idx = libname.Last('.');
6027 if (idx != kNPOS) {
6028 libname.Remove(idx);
6029 }
6030 size_t len = libname.Length();
6031 TEnvRec *rec;
6032 TIter next(fMapfile->GetTable());
6034 Int_t ret = 0;
6035 while ((rec = (TEnvRec *) next())) {
6036 TString cls = rec->GetName();
6037 if (cls.Length() > 2) {
6038 // get the first lib from the list of lib and dependent libs
6039 TString libs = rec->GetValue();
6040 if (libs == "") {
6041 continue;
6042 }
6043 TString delim(" ");
6044 TObjArray* tokens = libs.Tokenize(delim);
6045 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6046 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6047 // convert "@@" to "::", we used "@@" because TEnv
6048 // considers "::" a terminator
6049 cls.Remove(0, 8);
6050 cls.ReplaceAll("@@", "::");
6051 // convert "-" to " ", since class names may have
6052 // blanks and TEnv considers a blank a terminator
6053 cls.ReplaceAll("-", " ");
6054 }
6055 if (!strncmp(lib, libname.Data(), len)) {
6056 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6057 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6058 ret = -1;
6059 }
6060 }
6061 delete tokens;
6062 }
6063 }
6064 if (ret >= 0) {
6065 TString library_rootmap(library);
6066 if (!library_rootmap.EndsWith(".rootmap"))
6067 library_rootmap.Append(".rootmap");
6068 TNamed* mfile = nullptr;
6069 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6070 fRootmapFiles->Remove(mfile);
6071 delete mfile;
6072 }
6073 fRootmapFiles->Compress();
6074 }
6075 return ret;
6076}
6077
6078////////////////////////////////////////////////////////////////////////////////
6079/// Register the AutoLoading information for a class.
6080/// libs is a space separated list of libraries.
6081
6082Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6083{
6084 if (!cls || !*cls)
6085 return 0;
6086
6087 TString key = TString("Library.") + cls;
6088 // convert "::" to "@@", we used "@@" because TEnv
6089 // considers "::" a terminator
6090 key.ReplaceAll("::", "@@");
6091 // convert "-" to " ", since class names may have
6092 // blanks and TEnv considers a blank a terminator
6093 key.ReplaceAll(" ", "-");
6094
6096 if (!fMapfile) {
6097 fMapfile = new TEnv();
6098 fMapfile->IgnoreDuplicates(kTRUE);
6099
6101 fRootmapFiles->SetOwner();
6102
6103 InitRootmapFile(".rootmap");
6104 }
6105 //fMapfile->SetValue(key, libs);
6106 fMapfile->SetValue(cls, libs);
6107 return 1;
6108}
6109
6110////////////////////////////////////////////////////////////////////////////////
6111/// Demangle the name (from the typeinfo) and then request the class
6112/// via the usual name based interface (TClass::GetClass).
6113
6114TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6115{
6116 int err = 0;
6117 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6118 if (err) return nullptr;
6119 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6120 free(demangled_name);
6121 return theClass;
6122}
6123
6124////////////////////////////////////////////////////////////////////////////////
6125/// Load library containing the specified class. Returns 0 in case of error
6126/// and 1 in case if success.
6127
6128Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6129{
6130 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6131
6132 int err = 0;
6133 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6134 if (err) {
6135 return 0;
6136 }
6137
6138 std::string demangled_name(demangled_name_c);
6139 free(demangled_name_c);
6140
6141 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6142 // shortened name.
6144 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6145
6146 // No need to worry about typedef, they aren't any ... but there are
6147 // inlined namespaces ...
6148
6149 Int_t result = AutoLoad(demangled_name.c_str());
6150 if (result == 0) {
6151 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6152 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6153 }
6154
6155 return result;
6156}
6157
6158////////////////////////////////////////////////////////////////////////////////
6159// Get the list of 'published'/'known' library for the class and load them.
6161{
6162 Int_t status = 0;
6163
6164 // lookup class to find list of dependent libraries
6165 TString deplibs = gCling->GetClassSharedLibs(cls);
6166 if (!deplibs.IsNull()) {
6167 TString delim(" ");
6168 TObjArray* tokens = deplibs.Tokenize(delim);
6169 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6170 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6171 if (gROOT->LoadClass(cls, deplib) == 0) {
6172 if (gDebug > 0) {
6173 gCling->Info("TCling::AutoLoad",
6174 "loaded dependent library %s for %s", deplib, cls);
6175 }
6176 }
6177 else {
6178 gCling->Error("TCling::AutoLoad",
6179 "failure loading dependent library %s for %s",
6180 deplib, cls);
6181 }
6182 }
6183 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6184 if (lib && lib[0]) {
6185 if (gROOT->LoadClass(cls, lib) == 0) {
6186 if (gDebug > 0) {
6187 gCling->Info("TCling::AutoLoad",
6188 "loaded library %s for %s", lib, cls);
6189 }
6190 status = 1;
6191 }
6192 else {
6193 gCling->Error("TCling::AutoLoad",
6194 "failure loading library %s for %s", lib, cls);
6195 }
6196 }
6197 delete tokens;
6198 }
6199
6200 return status;
6201}
6202
6203////////////////////////////////////////////////////////////////////////////////
6204// Iterate through the data member of the class (either through the TProtoClass
6205// or through Cling) and trigger, recursively, the loading the necessary libraries.
6206// \note `cls` is expected to be already normalized!
6207// \returns 1 on success.
6208Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6209 bool nameIsNormalized)
6210{
6211 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6212 // has previously (within the same call to `AutoLoad()`) tried to load this class
6213 // and we are done, whether success or not, as it won't work better now than before,
6214 // because there is no additional information now compared to before.
6215 if (!visited.insert(std::string(cls)).second)
6216 return 1;
6217
6218 if (ShallowAutoLoadImpl(cls) == 0) {
6219 // If ShallowAutoLoadImpl() has an error, we have an error.
6220 return 0;
6221 }
6222
6223 // Now look through the TProtoClass to load the required library/dictionary
6224 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6225 for (auto element : proto->GetData()) {
6226 if (element->IsBasic())
6227 continue;
6228 const char *subtypename = element->GetTypeName();
6229 if (!TClassTable::GetDictNorm(subtypename)) {
6230 // Failure to load a dictionary is not (quite) a failure load
6231 // the top-level library. If we return false here, then
6232 // we would end up in a situation where the library and thus
6233 // the dictionary is loaded for "cls" but the TClass is
6234 // not created and/or marked as unavailable (in case where
6235 // AutoLoad is called from TClass::GetClass).
6236 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6237 }
6238 }
6239 return 1;
6240 }
6241
6242 // We found no TProtoClass for cls.
6243 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6244 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6245 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6246 {
6247 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6248 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6249 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6250 continue;
6251 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6252 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6253 // Failure to load a dictionary is not (quite) a failure load
6254 // the top-level library. See detailed comment in the TProtoClass
6255 // branch (above).
6256 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6257 }
6258 }
6259 gInterpreter->DataMemberInfo_Delete(memberinfo);
6260 }
6261 gInterpreter->ClassInfo_Delete(classinfo);
6262 return 1;
6263}
6264
6265////////////////////////////////////////////////////////////////////////////////
6266/// Load library containing the specified class. Returns 0 in case of error
6267/// and 1 in case if success.
6268
6269Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6270{
6271 // Prevent update to IsClassAutoloading between our check and our actions.
6273
6274 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6275 // rootcling (in *_rdict.pcm file generation) it is a no op.
6276 // FIXME: We should avoid calling autoload when we know we are not supposed
6277 // to and transform this check into an assert.
6279 // Never load any library from rootcling/genreflex.
6280 if (gDebug > 2) {
6281 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6282 }
6283 return 0;
6284 }
6285
6286 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6287
6289
6290 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6291 // The library is already loaded as the class's dictionary is known.
6292 // Return success.
6293 // Note: the name (cls) is expected to be normalized as it comes either
6294 // from a callbacks (that can/should calculate the normalized name from the
6295 // decl) or from TClass::GetClass (which does also calculate the normalized
6296 // name).
6297 return 1;
6298 }
6299
6300 if (gDebug > 2) {
6301 Info("TCling::AutoLoad",
6302 "Trying to autoload for %s", cls);
6303 }
6304
6305 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6306 if (gDebug > 2) {
6307 Info("TCling::AutoLoad",
6308 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6309 }
6310 return 0;
6311 }
6312 // Prevent the recursion when the library dictionary are loaded.
6313 SuspendAutoLoadingRAII autoLoadOff(this);
6314 // Try using externally provided callback first.
6315 if (fAutoLoadCallBack) {
6316 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6317 if (success)
6318 return success;
6319 }
6320
6321 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6322 // (when module are enabled) which might end up calling AutoParsing but
6323 // that should only be for the cases where the library has no generated pcm
6324 // and in that case a rootmap should be available.
6325 // This avoids a very costly operation (for generally no gain) but reduce the
6326 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6327 // file).
6328 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6329 std::unordered_set<std::string> visited;
6330 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6331}
6332
6333////////////////////////////////////////////////////////////////////////////////
6334/// Parse the payload or header.
6335
6336static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6337 Bool_t header,
6338 cling::Interpreter *interpreter)
6339{
6340 std::string code = gNonInterpreterClassDef ;
6341 if (!header) {
6342 // This is the complete header file content and not the
6343 // name of a header.
6344 code += what;
6345
6346 } else {
6347 code += ("#include \"");
6348 code += what;
6349 code += "\"\n";
6350 }
6351 code += ("#ifdef __ROOTCLING__\n"
6352 "#undef __ROOTCLING__\n"
6353 + gInterpreterClassDef +
6354 "#endif");
6355
6356 cling::Interpreter::CompilationResult cr;
6357 {
6358 // scope within which diagnostics are de-activated
6359 // For now we disable diagnostics because we saw them already at
6360 // dictionary generation time. That won't be an issue with the PCMs.
6361
6362 Sema &SemaR = interpreter->getSema();
6363 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6364 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6365
6366 #if defined(R__MUST_REVISIT)
6367 #if R__MUST_REVISIT(6,2)
6368 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6369 #endif
6370 #endif
6371
6372 cr = interpreter->parseForModule(code);
6373 }
6374 return cr;
6375}
6376
6377////////////////////////////////////////////////////////////////////////////////
6378/// Helper routine for TCling::AutoParse implementing the actual call to the
6379/// parser and looping over template parameters (if
6380/// any) and when they don't have a registered header to autoparse,
6381/// recurse over their template parameters.
6382///
6383/// Returns the number of header parsed.
6384
6385UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6386{
6387 // We assume the lock has already been taken.
6388 // R__LOCKGUARD(gInterpreterMutex);
6389
6390 Int_t nHheadersParsed = 0;
6391 unsigned long offset = 0;
6392 if (strncmp(cls, "const ", 6) == 0) {
6393 offset = 6;
6394 }
6395
6396 // Loop on the possible autoparse keys
6397 bool skipFirstEntry = false;
6398 std::vector<std::string> autoparseKeys;
6399 if (strchr(cls, '<')) {
6400 int nestedLoc = 0;
6401 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6402 // Check if we can skip the name of the template in the autoparses
6403 // Take all the scopes one by one. If all of them are in the AST, we do not
6404 // need to autoparse for that particular template.
6405 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6406 // autoparseKeys[0] is empty when the input is not a template instance.
6407 // The case strchr(cls, '<') != 0 but still not a template instance can
6408 // happens 'just' for string (GetSplit replaces the template by the short name
6409 // and then use that for thew splitting)
6410 TString templateName(autoparseKeys[0]);
6411 auto tokens = templateName.Tokenize("::");
6412 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6413 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6414 if (TClassEdit::IsStdClass(cls + offset))
6415 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6416 auto nTokens = tokens->GetEntriesFast();
6417 for (Int_t tk = 0; tk < nTokens; ++tk) {
6418 auto scopeObj = tokens->UncheckedAt(tk);
6419 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6420 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6421 // Check if we have multiple nodes in the AST with this name
6422 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6423 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6424 if (!previousScopeAsContext) break; // this is not a context
6425 }
6426 delete tokens;
6427 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6428 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6429 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6430 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6431 skipFirstEntry = templatedDecl->hasDefinition();
6432 }
6433 }
6434 }
6435
6436 }
6437 }
6438 if (topLevel) autoparseKeys.emplace_back(cls);
6439
6440 for (const auto & apKeyStr : autoparseKeys) {
6441 if (skipFirstEntry) {
6442 skipFirstEntry=false;
6443 continue;
6444 }
6445 if (apKeyStr.empty()) continue;
6446 const char *apKey = apKeyStr.c_str();
6447 std::size_t normNameHash(fStringHashFunction(apKey));
6448 // If the class was not looked up
6449 if (gDebug > 1) {
6450 Info("TCling::AutoParse",
6451 "Starting autoparse for %s\n", apKey);
6452 }
6453 if (fLookedUpClasses.insert(normNameHash).second) {
6454 auto const &iter = fClassesHeadersMap.find(normNameHash);
6455 if (iter != fClassesHeadersMap.end()) {
6456 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6457 fTransactionHeadersMap.insert({T,normNameHash});
6458 auto const &hNamesPtrs = iter->second;
6459 if (gDebug > 1) {
6460 Info("TCling::AutoParse",
6461 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6462 }
6463 for (auto & hName : hNamesPtrs) {
6464 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6465 if (0 != fPayloads.count(normNameHash)) {
6466 float initRSSval=0.f, initVSIZEval=0.f;
6467 (void) initRSSval; // Avoid unused var warning
6468 (void) initVSIZEval;
6469 if (gDebug > 0) {
6470 Info("AutoParse",
6471 "Parsing full payload for %s", apKey);
6472 ProcInfo_t info;
6473 gSystem->GetProcInfo(&info);
6474 initRSSval = 1e-3*info.fMemResident;
6475 initVSIZEval = 1e-3*info.fMemVirtual;
6476 }
6477 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6478 if (cRes != cling::Interpreter::kSuccess) {
6479 if (hName[0] == '\n')
6480 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6481 } else {
6482 fParsedPayloadsAddresses.insert(hName);
6483 nHheadersParsed++;
6484 if (gDebug > 0){
6485 ProcInfo_t info;
6486 gSystem->GetProcInfo(&info);
6487 float endRSSval = 1e-3*info.fMemResident;
6488 float endVSIZEval = 1e-3*info.fMemVirtual;
6489 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6490 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6491 }
6492 }
6493 } else if (!IsLoaded(hName)) {
6494 if (gDebug > 0) {
6495 Info("AutoParse",
6496 "Parsing single header %s", hName);
6497 }
6498 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6499 if (cRes != cling::Interpreter::kSuccess) {
6500 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6501 } else {
6502 nHheadersParsed++;
6503 }
6504 }
6505 }
6506 }
6507 else {
6508 // There is no header registered for this class, if this a
6509 // template, it will be instantiated if/when it is requested
6510 // and if we do no load/parse its components we might end up
6511 // not using an eventual specialization.
6512 if (strchr(apKey, '<')) {
6513 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6514 }
6515 }
6516 }
6517 }
6518
6519 return nHheadersParsed;
6520
6521}
6522
6523////////////////////////////////////////////////////////////////////////////////
6524/// Parse the headers relative to the class
6525/// Returns 1 in case of success, 0 in case of failure
6526
6527Int_t TCling::AutoParse(const char *cls)
6528{
6529 if (llvm::StringRef(cls).contains("(lambda)"))
6530 return 0;
6531
6533 if (fClingCallbacks->IsAutoLoadingEnabled()) {
6534 return AutoLoad(cls);
6535 } else {
6536 return 0;
6537 }
6538 }
6539
6541
6542 if (gDebug > 1) {
6543 Info("TCling::AutoParse",
6544 "Trying to autoparse for %s", cls);
6545 }
6546
6547 // The catalogue of headers is in the dictionary
6548 if (fClingCallbacks->IsAutoLoadingEnabled()
6549 && !gClassTable->GetDictNorm(cls)) {
6550 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6551 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6552 fInterpreter->getSema());
6553 AutoLoad(cls, true /*knowDictNotLoaded*/);
6554 }
6555
6556 // Prevent the recursion when the library dictionary are loaded.
6557 SuspendAutoLoadingRAII autoLoadOff(this);
6558
6559 // No recursive header parsing on demand; we require headers to be standalone.
6560 SuspendAutoParsing autoParseRAII(this);
6561
6562 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6563
6565
6566 return nHheadersParsed > 0 ? 1 : 0;
6567}
6568
6569// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6570// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6571// false if not.
6572bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6573{
6574 StringRef errMsg(errmessage);
6575 if (errMsg.contains("undefined symbol: ")) {
6576 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6577 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6578 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6579 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6580 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6581 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6582 return true;
6583 } else {
6584 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6585 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6586 return true;
6587 }
6588
6589 return false;
6590}
6591
6592////////////////////////////////////////////////////////////////////////////////
6593/// Autoload a library based on a missing symbol.
6594
6595void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6596 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6597
6598 // We have already loaded the library.
6599 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6600 return Addr;
6601
6602 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6604
6605 auto LibLoader = [](const std::string& LibName) -> bool {
6606 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6607 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6608 "Failed to load library %s", LibName.c_str());
6609 return false;
6610 }
6611 return true; //success.
6612 };
6613
6614 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6615 /*searchSystem=*/ true);
6616
6617 assert(!llvm::StringRef(libName).startswith("libNew") &&
6618 "We must not resolve symbols from libNew!");
6619
6620 if (libName.empty())
6621 return nullptr;
6622
6623 if (!LibLoader(libName))
6624 return nullptr;
6625
6626 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6627}
6628
6629////////////////////////////////////////////////////////////////////////////////
6630
6631Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6632{
6633 return fNSFromRootmaps.count(nsDecl) != 0;
6634}
6635
6636////////////////////////////////////////////////////////////////////////////////
6637/// Internal function. Actually do the update of the ClassInfo when seeing
6638// new TagDecl or NamespaceDecl.
6639void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6640{
6641
6643 if (cci) {
6644 // If we only had a forward declaration then update the
6645 // TClingClassInfo with the definition if we have it now.
6646 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6647 if (!oldDef || (def && def != oldDef)) {
6648 cl->ResetCaches();
6650 if (def) {
6651 // It's a tag decl, not a namespace decl.
6652 cci->Init(*cci->GetType());
6654 }
6655 }
6656 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6657 cl->ResetCaches();
6658 // yes, this is almost a waste of time, but we do need to lookup
6659 // the 'type' corresponding to the TClass anyway in order to
6660 // preserve the opaque typedefs (Double32_t)
6661 if (!alias && def != nullptr)
6662 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6663 else
6664 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6665 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6666 // We now need to update the state and bits.
6667 if (cl->fState != TClass::kHasTClassInit) {
6668 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6670 }
6671 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6672 } else {
6673 delete ((TClingClassInfo *)cl->fClassInfo);
6674 cl->fClassInfo = nullptr;
6675 }
6676 }
6677}
6678
6679////////////////////////////////////////////////////////////////////////////////
6680/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6681void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6682{
6683 const TagDecl *td = dyn_cast<TagDecl>(ND);
6684 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6685 const NamedDecl *canon = nullptr;
6686
6687 std::string name;
6688 TagDecl* tdDef = nullptr;
6689 if (td) {
6690 canon = tdDef = td->getDefinition();
6691 // Let's pass the decl to the TClass only if it has a definition.
6692 if (!tdDef) return;
6693
6694 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6695 // Ignore incomplete definition.
6696 // Ignore declaration within a function.
6697 return;
6698 }
6699
6700 auto declName = tdDef->getNameAsString();
6701 // Check if we have registered the unqualified name into the list
6702 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6703 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6704 // the unqualified name is sufficient (and the fully qualified name might be
6705 // 'wrong' if there is difference in spelling in the template paramters (for example)
6706 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6707 // 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() );
6708 return;
6709 }
6710
6711 clang::QualType type(tdDef->getTypeForDecl(), 0);
6713 } else if (ns) {
6714 canon = ns->getCanonicalDecl();
6715 name = ND->getQualifiedNameAsString();
6716 } else {
6717 name = ND->getQualifiedNameAsString();
6718 }
6719
6720 // Supposedly we are being called while something is being
6721 // loaded ... let's now tell the autoloader to do the work
6722 // yet another time.
6723 SuspendAutoLoadingRAII autoLoadOff(this);
6724 // FIXME: There can be more than one TClass for a single decl.
6725 // for example vector<double> and vector<Double32_t>
6726 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6727 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6728 RefreshClassInfo(cl, canon, false);
6729 }
6730 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6731 // and update them too:
6732 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6733 // RefreshClassInfo(cl, tdDef, true);
6734}
6735
6736////////////////////////////////////////////////////////////////////////////////
6737/// No op: see TClingCallbacks
6738
6739void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6740{
6741}
6742
6743//______________________________________________________________________________
6744//FIXME: Factor out that function in TClass, because TClass does it already twice
6745void TCling::UpdateClassInfoWork(const char* item)
6746{
6747 // This is a no-op as part of the API.
6748 // TCling uses UpdateClassInfoWithDecl() instead.
6749}
6750
6751////////////////////////////////////////////////////////////////////////////////
6752/// Update all canvases at end the terminal input command.
6753
6755{
6756 TIter next(gROOT->GetListOfCanvases());
6757 TVirtualPad* canvas;
6758 while ((canvas = (TVirtualPad*)next())) {
6759 canvas->Update();
6760 }
6761}
6762
6763////////////////////////////////////////////////////////////////////////////////
6764
6765void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6766 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6767
6768 // If the transaction does not contain anything we can return earlier.
6769 if (!HandleNewTransaction(T)) return;
6770
6771 bool isTUTransaction = false;
6772 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6773 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6774 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6775 // The is the first transaction, we have to expose to meta
6776 // what's already in the AST.
6777 isTUTransaction = true;
6778 }
6779 }
6780
6781 std::set<const void*> TransactionDeclSet;
6782 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6783 const clang::Decl* WrapperFD = T.getWrapperFD();
6784 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6785 I != E; ++I) {
6786 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6787 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6788 continue;
6789
6790 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6791 DE = I->m_DGR.end(); DI != DE; ++DI) {
6792 if (*DI == WrapperFD)
6793 continue;
6794 TransactionDeclSet.insert(*DI);
6795 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6796 }
6797 }
6798 }
6799
6800 // The above might trigger more decls to be deserialized.
6801 // Thus the iteration over the deserialized decls must be last.
6802 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6803 E = T.deserialized_decls_end(); I != E; ++I) {
6804 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6805 DE = I->m_DGR.end(); DI != DE; ++DI)
6806 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6807 //FIXME: HandleNewDecl should take DeclGroupRef
6808 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6809 modifiedTClasses);
6810 }
6811 }
6812
6813
6814 // When fully building the reflection info in TClass, a deserialization
6815 // could be triggered, which may result in request for building the
6816 // reflection info for the same TClass. This in turn will clear the caches
6817 // for the TClass in-flight and cause null ptr derefs.
6818 // FIXME: This is a quick fix, solving most of the issues. The actual
6819 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6820 // itself until the update is done.
6821 //
6822 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6823 std::vector<TClass*>::iterator it;
6824 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6825 ((TCling*)gCling)->GetModTClasses().begin(),
6826 ((TCling*)gCling)->GetModTClasses().end(),
6827 modifiedTClassesDiff.begin());
6828 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6829
6830 // Lock the TClass for updates
6831 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6832 modifiedTClassesDiff.end());
6833 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6834 E = modifiedTClassesDiff.end(); I != E; ++I) {
6835 // Make sure the TClass has not been deleted.
6836 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6837 continue;
6838 }
6839 // Could trigger deserialization of decls.
6840 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6841 // Unlock the TClass for updates
6842 ((TCling*)gCling)->GetModTClasses().erase(*I);
6843
6844 }
6845}
6846
6847///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6848///
6849void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6850{
6852
6853 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6854 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6855 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6856 (TListOfEnums *)gROOT->GetListOfEnums());
6857
6858 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6859 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6860 I != E; ++I) {
6861 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6862 continue;
6863 if (I->m_Call == cling::Transaction::kCCINone) {
6864 UpdateListsOnUnloaded(*(*iNested));
6865 ++iNested;
6866 continue;
6867 }
6868
6869 for (auto &D : I->m_DGR)
6870 InvalidateCachedDecl(Lists, D);
6871 }
6872}
6873
6874///\brief Invalidate cached TCling information for the given global declaration.
6875///
6876void TCling::InvalidateGlobal(const Decl *D) {
6877 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6878 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6879 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6880 (TListOfEnums *)gROOT->GetListOfEnums());
6881 InvalidateCachedDecl(Lists, D);
6882}
6883
6884///\brief Invalidate cached TCling information for the given declaration, and
6885/// removed it from the appropriate object list.
6886///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6887/// TListOfFunctionTemplates&, TListOfEnums&>
6888/// of pointers to the (global/class) object lists.
6889///\param[in] D - Decl to discard.
6890///
6894 TListOfEnums*> &Lists, const Decl *D) {
6895 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6896 return;
6897
6898 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6899 TListOfFunctions &LOF = *(std::get<1>(Lists));
6900 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6901 TListOfEnums &LOE = *(std::get<3>(Lists));
6902
6903 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6904 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6905 if (LODM.GetClass())
6906 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6907 else
6908 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6909 } else if (isa<FunctionDecl>(D)) {
6911 } else if (isa<FunctionTemplateDecl>(D)) {
6913 } else if (isa<EnumDecl>(D)) {
6914 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6915 if (!E)
6916 return;
6917
6918 // Try to invalidate enumerators (for unscoped enumerations).
6919 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6921 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6922
6924 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6925 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6926 return;
6927
6928 std::vector<TClass *> Classes;
6929 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6930 return;
6931 for (auto &C : Classes) {
6932 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6933 (TListOfFunctions *)C->GetListOfMethods(),
6934 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6935 (TListOfEnums *)C->GetListOfEnums());
6936 for (auto &I : cast<DeclContext>(D)->decls())
6937 InvalidateCachedDecl(Lists, I);
6938
6939 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6940 if (D->getKind() != Decl::Namespace
6941 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6942 C->ResetClassInfo();
6943 }
6944 }
6945}
6946
6947////////////////////////////////////////////////////////////////////////////////
6948// If an autoparse was done during a transaction and that it is rolled back,
6949// we need to make sure the next request for the same autoparse will be
6950// honored.
6951void TCling::TransactionRollback(const cling::Transaction &T) {
6952 auto const &triter = fTransactionHeadersMap.find(&T);
6953 if (triter != fTransactionHeadersMap.end()) {
6954 std::size_t normNameHash = triter->second;
6955
6956 fLookedUpClasses.erase(normNameHash);
6957
6958 auto const &iter = fClassesHeadersMap.find(normNameHash);
6959 if (iter != fClassesHeadersMap.end()) {
6960 auto const &hNamesPtrs = iter->second;
6961 for (auto &hName : hNamesPtrs) {
6962 if (gDebug > 0) {
6963 Info("TransactionRollback",
6964 "Restoring ability to autoaparse: %s", hName);
6965 }
6966 fParsedPayloadsAddresses.erase(hName);
6967 }
6968 }
6969 }
6970}
6971
6972////////////////////////////////////////////////////////////////////////////////
6973
6974void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6975// R__LOCKGUARD_CLING(gInterpreterMutex);
6976// UpdateListOfLoadedSharedLibraries();
6977}
6978
6979////////////////////////////////////////////////////////////////////////////////
6980
6981void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6982 fPrevLoadedDynLibInfo = nullptr;
6983 fSharedLibs = "";
6984}
6985
6986////////////////////////////////////////////////////////////////////////////////
6987/// Return the list of shared libraries loaded into the process.
6988
6995
6996static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6997{
6998 if (!cls || !*cls)
6999 return {};
7000
7001 using namespace clang;
7002 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7003 /*type*/ nullptr, /*instantiate*/ false)) {
7004 if (!D->isFromASTFile()) {
7005 if (gDebug > 5)
7006 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7007 return {};
7008 }
7009 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7010 llvm::DenseSet<Module *> &m_TopLevelModules;
7011
7012 public:
7013 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7014 void Collect(const Decl *D) { Visit(D); }
7015
7016 void VisitDecl(const Decl *D)
7017 {
7018 // FIXME: Such case is described ROOT-7765 where
7019 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7020 // They are specified as #includes in the LinkDef file. This leads to
7021 // generation of incomplete modulemap files and this logic fails to
7022 // compute the corresponding module of D.
7023 // FIXME: If we want to support such a case, we should not rely on
7024 // the contents of the modulemap but mangle D and look it up in the
7025 // .so files.
7026 if (!D->hasOwningModule())
7027 return;
7028 if (Module *M = D->getOwningModule()->getTopLevelModule())
7029 m_TopLevelModules.insert(M);
7030 }
7031
7032 void VisitTemplateArgument(const TemplateArgument &TA)
7033 {
7034 switch (TA.getKind()) {
7035 case TemplateArgument::Null:
7036 case TemplateArgument::Integral:
7037 case TemplateArgument::Pack:
7038 case TemplateArgument::NullPtr:
7039 case TemplateArgument::Expression:
7040 case TemplateArgument::Template:
7041 case TemplateArgument::TemplateExpansion: return;
7042 case TemplateArgument::Type:
7043 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7044 return Visit(TagTy->getDecl());
7045 return;
7046 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7047 }
7048 llvm_unreachable("Invalid TemplateArgument::Kind!");
7049 }
7050
7051 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7052 {
7053 if (CTSD->getOwningModule())
7054 VisitDecl(CTSD);
7055 else
7056 VisitDecl(CTSD->getSpecializedTemplate());
7057 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7058 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7059 VisitTemplateArgument(*Arg);
7060 }
7061 }
7062 };
7063
7064 llvm::DenseSet<Module *> TopLevelModules;
7065 ModuleCollector m(TopLevelModules);
7066 m.Collect(D);
7067 std::string result;
7068 for (auto M : TopLevelModules) {
7069 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7070 // link declaration.
7071 if (!M->LinkLibraries.size())
7072 continue;
7073 // We have preloaded the Core module thus libCore.so
7074 if (M->Name == "Core")
7075 continue;
7076 assert(M->LinkLibraries.size() == 1);
7077 if (!result.empty())
7078 result += ' ';
7079 result += M->LinkLibraries[0].Library;
7080 }
7081 return result;
7082 }
7083 return {};
7084}
7085
7086////////////////////////////////////////////////////////////////////////////////
7087/// Get the list of shared libraries containing the code for class cls.
7088/// The first library in the list is the one containing the class, the
7089/// others are the libraries the first one depends on. Returns 0
7090/// in case the library is not found.
7091
7092const char* TCling::GetClassSharedLibs(const char* cls)
7093{
7094 if (fCxxModulesEnabled) {
7095 // Lock the interpreter mutex before interacting with cling.
7096 // TODO: Can we move this further deep? In principle the lock should be in
7097 // GetClassSharedLibsForModule, but it might be needed also for
7098 // getLookupHelper?
7100 llvm::StringRef className = cls;
7101 // If we get a class name containing lambda, we cannot parse it and we
7102 // can exit early.
7103 // FIXME: This works around a bug when we are instantiating a template
7104 // make_unique and the substitution fails. Seen in most of the dataframe
7105 // tests.
7106 if (className.contains("(lambda)"))
7107 return nullptr;
7108 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7109 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7110 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7111 std::string libs = GetClassSharedLibsForModule(cls, LH);
7112 if (!libs.empty()) {
7113 fAutoLoadLibStorage.push_back(libs);
7114 return fAutoLoadLibStorage.back().c_str();
7115 }
7116 }
7117
7118 if (!cls || !*cls) {
7119 return nullptr;
7120 }
7121 // lookup class to find list of libraries
7122 if (fMapfile) {
7123 TEnvRec* libs_record = nullptr;
7124 libs_record = fMapfile->Lookup(cls);
7125 if (libs_record) {
7126 const char* libs = libs_record->GetValue();
7127 return (*libs) ? libs : nullptr;
7128 }
7129 else {
7130 // Try the old format...
7131 TString c = TString("Library.") + cls;
7132 // convert "::" to "@@", we used "@@" because TEnv
7133 // considers "::" a terminator
7134 c.ReplaceAll("::", "@@");
7135 // convert "-" to " ", since class names may have
7136 // blanks and TEnv considers a blank a terminator
7137 c.ReplaceAll(" ", "-");
7138 // Use TEnv::Lookup here as the rootmap file must start with Library.
7139 // and do not support using any stars (so we do not need to waste time
7140 // with the search made by TEnv::GetValue).
7141 TEnvRec* libs_record = nullptr;
7142 libs_record = fMapfile->Lookup(c);
7143 if (libs_record) {
7144 const char* libs = libs_record->GetValue();
7145 return (*libs) ? libs : nullptr;
7146 }
7147 }
7148 }
7149 return nullptr;
7150}
7151
7152/// This interface returns a list of dependent libraries in the form:
7153/// lib libA.so libB.so libC.so. The first library is the library we are
7154/// searching dependencies for.
7155/// Note: In order to speed up the search, we display the dependencies of the
7156/// libraries which are not yet loaded. For instance, if libB.so was already
7157/// loaded the list would contain: lib libA.so libC.so.
7158static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7159 cling::Interpreter *interp,
7160 bool skipLoadedLibs = true)
7161{
7162 TString LibFullPath(lib);
7163 if (!llvm::sys::path::is_absolute(lib)) {
7164 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7165 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7166 return "";
7167 }
7168 } else {
7169 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7170 lib = llvm::sys::path::filename(lib).str();
7171 }
7172
7173 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7174 if (!ObjF) {
7175 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7176 return "";
7177 }
7178
7179 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7180
7181 std::set<string> DedupSet;
7182 std::string Result = lib + ' ';
7183 for (const auto &S : BinObjFile->symbols()) {
7184 uint32_t Flags = llvm::cantFail(S.getFlags());
7185 // Skip defined symbols: we have them.
7186 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7187 continue;
7188 // Skip undefined weak symbols: if we don't have them we won't need them.
7189 // `__gmon_start__` being a typical example.
7190 if (Flags & llvm::object::SymbolRef::SF_Weak)
7191 continue;
7192 llvm::Expected<StringRef> SymNameErr = S.getName();
7193 if (!SymNameErr) {
7194 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7195 continue;
7196 }
7197 llvm::StringRef SymName = SymNameErr.get();
7198 if (SymName.empty())
7199 continue;
7200
7201 if (BinObjFile->isELF()) {
7202 // Skip the symbols which are part of the C/C++ runtime and have a
7203 // fixed library version. See binutils ld VERSION. Those reside in
7204 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7205 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7206 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7207 continue;
7208
7209 // Those are 'weak undefined' symbols produced by gcc. We can
7210 // ignore them.
7211 // FIXME: It is unclear whether we can ignore all weak undefined
7212 // symbols:
7213 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7214 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7215 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7216 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7217 if (SymName == RegisterClasses ||
7218 SymName == RegisterCloneTable ||
7219 SymName == DeregisterCloneTable)
7220 continue;
7221 }
7222
7223 // If we can find the address of the symbol, we have loaded it. Skip.
7224 if (skipLoadedLibs) {
7225 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7226 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7227 continue;
7228 }
7229
7231 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7232 // The expected output is just filename without the full path, which
7233 // is not very accurate, because our Dyld implementation might find
7234 // a match in location a/b/c.so and if we return just c.so ROOT might
7235 // resolve it to y/z/c.so and there we might not be ABI compatible.
7236 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7237 if (!found.empty()) {
7238 std::string cand = llvm::sys::path::filename(found).str();
7239 if (!DedupSet.insert(cand).second)
7240 continue;
7241
7242 Result += cand + ' ';
7243 }
7244 }
7245
7246 return Result;
7247}
7248
7249static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7250{
7251 // Check if we have parsed a rootmap file.
7252 llvm::SmallString<256> rootmapName;
7253 if (!lib.startswith("lib"))
7254 rootmapName.append("lib");
7255
7256 rootmapName.append(llvm::sys::path::filename(lib));
7257 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7258
7259 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7260 return true;
7261
7262 // Perform a last resort by dropping the lib prefix.
7263 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7264 if (rootmapNameNoLib.consume_front("lib"))
7265 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7266
7267 return false;
7268}
7269
7270static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7271{
7272 if (gCling->HasPCMForLibrary(lib.data()))
7273 return true;
7274
7275 return hasParsedRootmapForLibrary(lib);
7276}
7277
7278////////////////////////////////////////////////////////////////////////////////
7279/// Get the list a libraries on which the specified lib depends. The
7280/// returned string contains as first element the lib itself.
7281/// Returns 0 in case the lib does not exist or does not have
7282/// any dependencies. If useDyld is true, we iterate through all available
7283/// libraries and try to construct the dependency chain by resolving each
7284/// symbol.
7285
7286const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7287{
7288 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7289 return nullptr;
7290
7291 if (!hasParsedRootmapForLibrary(lib)) {
7292 llvm::SmallString<512> rootmapName(lib);
7293 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7294 if (llvm::sys::fs::exists(rootmapName)) {
7295 if (gDebug > 0)
7296 Info("Load", "loading %s", rootmapName.c_str());
7297 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7298 }
7299 }
7300
7301 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7302 if (gDebug > 0)
7303 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7304 }
7305
7306 if (useDyld) {
7307 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7308 if (!libs.empty()) {
7309 fAutoLoadLibStorage.push_back(libs);
7310 return fAutoLoadLibStorage.back().c_str();
7311 }
7312 }
7313
7314 if (!fMapfile || !lib || !lib[0]) {
7315 return nullptr;
7316 }
7317 TString libname(lib);
7318 Ssiz_t idx = libname.Last('.');
7319 if (idx != kNPOS) {
7320 libname.Remove(idx);
7321 }
7322 TEnvRec* rec;
7323 TIter next(fMapfile->GetTable());
7324 size_t len = libname.Length();
7325 while ((rec = (TEnvRec*) next())) {
7326 const char* libs = rec->GetValue();
7327 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7328 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7329 return libs;
7330 }
7331 }
7332 return nullptr;
7333}
7334
7335////////////////////////////////////////////////////////////////////////////////
7336/// If error messages are disabled, the interpreter should suppress its
7337/// failures and warning messages from stdout.
7338
7340{
7341#if defined(R__MUST_REVISIT)
7342#if R__MUST_REVISIT(6,2)
7343 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7344#endif
7345#endif
7346 return kTRUE;
7347}
7348
7349////////////////////////////////////////////////////////////////////////////////
7350/// If error messages are disabled, the interpreter should suppress its
7351/// failures and warning messages from stdout. Return the previous state.
7352
7354{
7355#if defined(R__MUST_REVISIT)
7356#if R__MUST_REVISIT(6,2)
7357 Warning("SetErrorMessages", "Interface not available yet.");
7358#endif
7359#endif
7361}
7362
7363////////////////////////////////////////////////////////////////////////////////
7364/// Refresh the list of include paths known to the interpreter and return it
7365/// with -I prepended.
7366
7368{
7370
7371 fIncludePath = "";
7372
7373 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7374 //false - no system header, true - with flags.
7375 fInterpreter->GetIncludePaths(includePaths, false, true);
7376 if (const size_t nPaths = includePaths.size()) {
7377 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7378
7379 for (size_t i = 0; i < nPaths; i += 2) {
7380 if (i)
7381 fIncludePath.Append(' ');
7382 fIncludePath.Append(includePaths[i].c_str());
7383
7384 if (includePaths[i] != "-I")
7385 fIncludePath.Append(' ');
7386 fIncludePath.Append('"');
7387 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7388 fIncludePath.Append('"');
7389 }
7390 }
7391
7392 return fIncludePath;
7393}
7394
7395////////////////////////////////////////////////////////////////////////////////
7396/// Return the directory containing CINT's stl cintdlls.
7397
7398const char* TCling::GetSTLIncludePath() const
7399{
7400 return "";
7401}
7402
7403//______________________________________________________________________________
7404// M I S C
7405//______________________________________________________________________________
7406
7407int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7408{
7409 // Interface to cling function
7410 return 0;
7411}
7412
7413////////////////////////////////////////////////////////////////////////////////
7414/// Interface to cling function
7415
7416int TCling::DisplayIncludePath(FILE *fout) const
7417{
7418 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7419
7420 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7421 //false - no system header, true - with flags.
7422 fInterpreter->GetIncludePaths(includePaths, false, true);
7423 if (const size_t nPaths = includePaths.size()) {
7424 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7425
7426 std::string allIncludes("include path:");
7427 for (size_t i = 0; i < nPaths; i += 2) {
7428 allIncludes += ' ';
7429 allIncludes += includePaths[i];
7430
7431 if (includePaths[i] != "-I")
7432 allIncludes += ' ';
7433 allIncludes += includePaths[i + 1];
7434 }
7435
7436 fprintf(fout, "%s\n", allIncludes.c_str());
7437 }
7438
7439 return 0;
7440}
7441
7442////////////////////////////////////////////////////////////////////////////////
7443/// Interface to cling function
7444
7445void* TCling::FindSym(const char* entry) const
7446{
7448 return fInterpreter->getAddressOfGlobal(entry);
7449}
7450
7451////////////////////////////////////////////////////////////////////////////////
7452/// Let the interpreter issue a generic error, and set its error state.
7453
7454void TCling::GenericError(const char* error) const
7455{
7456#if defined(R__MUST_REVISIT)
7457#if R__MUST_REVISIT(6,2)
7458 Warning("GenericError","Interface not available yet.");
7459#endif
7460#endif
7461}
7462
7463////////////////////////////////////////////////////////////////////////////////
7464/// This routines used to return the address of the internal wrapper
7465/// function (of the interpreter) that was used to call *all* the
7466/// interpreted functions that were bytecode compiled (no longer
7467/// interpreted line by line). In Cling, there is no such
7468/// wrapper function.
7469/// In practice this routines was use to decipher whether the
7470/// pointer returns by InterfaceMethod could be used to uniquely
7471/// represent the function. In Cling if the function is in a
7472/// useable state (its compiled version is available), this is
7473/// always the case.
7474/// See TClass::GetMethod.
7475
7477{
7478 return 0;
7479}
7480
7481////////////////////////////////////////////////////////////////////////////////
7482/// Interface to cling function
7483
7485{
7486#if defined(R__MUST_REVISIT)
7487#if R__MUST_REVISIT(6,2)
7488 Warning("GetSecurityError", "Interface not available yet.");
7489#endif
7490#endif
7491 return 0;
7492}
7493
7494////////////////////////////////////////////////////////////////////////////////
7495/// Load a source file or library called path into the interpreter.
7496
7497int TCling::LoadFile(const char* path) const
7498{
7499 // Modifying the interpreter state needs locking.
7501 cling::Interpreter::CompilationResult compRes;
7502 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7503 return compRes == cling::Interpreter::kFailure;
7504}
7505
7506////////////////////////////////////////////////////////////////////////////////
7507/// Load the declarations from text into the interpreter.
7508/// Note that this cannot be (top level) statements; text must contain
7509/// top level declarations.
7510/// Returns true on success, false on failure.
7511
7512Bool_t TCling::LoadText(const char* text) const
7513{
7514 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7515}
7516
7517////////////////////////////////////////////////////////////////////////////////
7518/// Interface to cling function
7519
7520const char* TCling::MapCppName(const char* name) const
7521{
7522 TTHREAD_TLS_DECL(std::string,buffer);
7524 return buffer.c_str(); // NOLINT
7525}
7526
7527////////////////////////////////////////////////////////////////////////////////
7528/// [Place holder for Mutex Lock]
7529/// Provide the interpreter with a way to
7530/// acquire a lock used to protect critical section
7531/// of its code (non-thread safe parts).
7532
7533void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7534{
7535 // nothing to do for now.
7536}
7537
7538////////////////////////////////////////////////////////////////////////////////
7539/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7540/// release a lock used to protect critical section
7541/// of its code (non-thread safe parts).
7542
7543void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7544{
7545 // nothing to do for now.
7546}
7547
7548////////////////////////////////////////////////////////////////////////////////
7549/// Returns if class AutoLoading is currently enabled.
7550
7552{
7553 if (IsFromRootCling())
7554 return false;
7555 if (!fClingCallbacks)
7556 return false;
7557 return fClingCallbacks->IsAutoLoadingEnabled();
7558}
7559
7560////////////////////////////////////////////////////////////////////////////////
7561/// Enable/Disable the AutoLoading of libraries.
7562/// Returns the old value, i.e whether it was enabled or not.
7563
7564int TCling::SetClassAutoLoading(int autoload) const
7565{
7566 // If no state change is required, exit early.
7567 // FIXME: In future we probably want to complain if we made a request which
7568 // was with the same state as before in order to catch programming errors.
7569 if ((bool) autoload == IsClassAutoLoadingEnabled())
7570 return autoload;
7571
7572 assert(fClingCallbacks && "We must have callbacks!");
7573 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7574 fClingCallbacks->SetAutoLoadingEnabled(autoload);
7575 return oldVal;
7576}
7577
7578////////////////////////////////////////////////////////////////////////////////
7579/// Enable/Disable the Autoparsing of headers.
7580/// Returns the old value, i.e whether it was enabled or not.
7581
7583{
7584 bool oldVal = fHeaderParsingOnDemand;
7585 fHeaderParsingOnDemand = autoparse;
7586 return oldVal;
7587}
7588
7589////////////////////////////////////////////////////////////////////////////////
7590/// Suspend the Autoparsing of headers.
7591/// Returns the old value, i.e whether it was suspended or not.
7592
7599
7600////////////////////////////////////////////////////////////////////////////////
7601/// Set a callback to receive error messages.
7602
7603void TCling::SetErrmsgcallback(void* p) const
7604{
7605#if defined(R__MUST_REVISIT)
7606#if R__MUST_REVISIT(6,2)
7607 Warning("SetErrmsgcallback", "Interface not available yet.");
7608#endif
7609#endif
7610}
7611
7613{
7614 if (enable) {
7615 auto consumer = new TClingDelegateDiagnosticPrinter(
7616 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7617 fInterpreter->getCI()->getLangOpts(),
7618 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7619 if (Level == clang::DiagnosticsEngine::Warning) {
7620 ::Warning("cling", "%s", Info.c_str());
7621 } else if (Level == clang::DiagnosticsEngine::Error
7622 || Level == clang::DiagnosticsEngine::Fatal) {
7623 ::Error("cling", "%s", Info.c_str());
7624 } else {
7625 ::Info("cling", "%s", Info.c_str());
7626 }
7627 });
7628 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7629 } else {
7630 fInterpreter->replaceDiagnosticConsumer(nullptr);
7631 }
7632}
7633
7634
7635////////////////////////////////////////////////////////////////////////////////
7636/// Create / close a scope for temporaries. No-op for cling; use
7637/// cling::Value instead.
7638
7639void TCling::SetTempLevel(int val) const
7640{
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644
7645int TCling::UnloadFile(const char* path) const
7646{
7647 // Modifying the interpreter state needs locking.
7649 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7650 std::string canonical = DLM->lookupLibrary(path);
7651 if (canonical.empty()) {
7652 canonical = path;
7653 }
7654 // Unload a shared library or a source file.
7655 cling::Interpreter::CompilationResult compRes;
7656 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7657 return compRes == cling::Interpreter::kFailure;
7658}
7659
7660std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7661 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7662}
7663
7664////////////////////////////////////////////////////////////////////////////////
7665/// The call to Cling's tab complition.
7666
7667void TCling::CodeComplete(const std::string& line, size_t& cursor,
7668 std::vector<std::string>& completions)
7669{
7670 fInterpreter->codeComplete(line, cursor, completions);
7671}
7672
7673////////////////////////////////////////////////////////////////////////////////
7674/// Get the interpreter value corresponding to the statement.
7676{
7678
7679 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7680 auto compRes = fInterpreter->evaluate(code, *V);
7681 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7682}
7683
7684////////////////////////////////////////////////////////////////////////////////
7685
7687{
7688 using namespace cling;
7689 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7691}
7692
7693////////////////////////////////////////////////////////////////////////////////
7694/// Register value as a temporary, extending its lifetime to that of the
7695/// interpreter. This is needed for TCling's compatibility interfaces
7696/// returning long - the address of the temporary objects.
7697/// As such, "simple" types don't need to be stored; they are returned by
7698/// value; only pointers / references / objects need to be stored.
7699
7700void TCling::RegisterTemporary(const cling::Value& value)
7701{
7702 if (value.isValid() && value.needsManagedAllocation()) {
7704 fTemporaries->push_back(value);
7705 }
7706}
7707
7708////////////////////////////////////////////////////////////////////////////////
7709/// If the interpreter encounters Name, check whether that is an object ROOT
7710/// could retrieve. To not re-read objects from disk, cache the name/object
7711/// pair for a given LookupCtx.
7712
7713TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7714{
7715 // The call to FindSpecialObject might induces any kind of use
7716 // of the interpreter ... (library loading, function calling, etc.)
7717 // ... and we _know_ we are in the middle of parsing, so let's make
7718 // sure to save the state and then restore it.
7719
7720 if (gDirectory) {
7721 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7722 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7723 auto iSpecObj = iSpecObjMap->second.find(Name);
7724 if (iSpecObj != iSpecObjMap->second.end()) {
7725 LookupCtx = gDirectory;
7726 return iSpecObj->second;
7727 }
7728 }
7729 }
7730
7731 // Save state of the PP
7732 Sema &SemaR = fInterpreter->getSema();
7733 ASTContext& C = SemaR.getASTContext();
7734 Preprocessor &PP = SemaR.getPreprocessor();
7735 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7736 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7737 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7738 // After we have saved the token reset the current one to something which
7739 // is safe (semi colon usually means empty decl)
7740 Token& Tok = const_cast<Token&>(P.getCurToken());
7741 Tok.setKind(tok::semi);
7742
7743 // We can't PushDeclContext, because we go up and the routine that pops
7744 // the DeclContext assumes that we drill down always.
7745 // We have to be on the global context. At that point we are in a
7746 // wrapper function so the parent context must be the global.
7747 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7748 SemaR.TUScope);
7749
7750 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7751 if (specObj) {
7752 if (!LookupCtx) {
7753 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7754 } else {
7755 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7756 }
7757 }
7758 return specObj;
7759}
7760
7761////////////////////////////////////////////////////////////////////////////////
7762/// Inject function as a friend into klass.
7763/// With function being f in void f() {new N::PrivKlass(); } this enables
7764/// I/O of non-public classes.
7765
7766void TCling::AddFriendToClass(clang::FunctionDecl* function,
7767 clang::CXXRecordDecl* klass) const
7768{
7769 using namespace clang;
7770 ASTContext& Ctx = klass->getASTContext();
7771 FriendDecl::FriendUnion friendUnion(function);
7772 // one dummy object for the source location
7773 SourceLocation sl;
7774 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7775 klass->pushFriendDecl(friendDecl);
7776}
7777
7778//______________________________________________________________________________
7779//
7780// DeclId getter.
7781//
7782
7783////////////////////////////////////////////////////////////////////////////////
7784/// Return a unique identifier of the declaration represented by the
7785/// CallFunc
7786
7788{
7789 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7790 return nullptr;
7791}
7792
7793////////////////////////////////////////////////////////////////////////////////
7794/// Return a (almost) unique identifier of the declaration represented by the
7795/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7796/// when the underlying class is a template instance involving one of the
7797/// opaque typedef.
7798
7800{
7801 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7802 return nullptr;
7803}
7804
7805////////////////////////////////////////////////////////////////////////////////
7806/// Return a unique identifier of the declaration represented by the
7807/// MethodInfo
7808
7810{
7811 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7812 return nullptr;
7813}
7814
7815////////////////////////////////////////////////////////////////////////////////
7816/// Return a unique identifier of the declaration represented by the
7817/// MethodInfo
7818
7820{
7821 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7822 return nullptr;
7823}
7824
7825////////////////////////////////////////////////////////////////////////////////
7826/// Return a unique identifier of the declaration represented by the
7827/// TypedefInfo
7828
7830{
7831 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7832 return nullptr;
7833}
7834
7835//______________________________________________________________________________
7836//
7837// CallFunc interface
7838//
7839
7840////////////////////////////////////////////////////////////////////////////////
7841
7842void TCling::CallFunc_Delete(CallFunc_t* func) const
7843{
7844 delete (TClingCallFunc*) func;
7845}
7846
7847////////////////////////////////////////////////////////////////////////////////
7848
7849void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7850{
7851 TClingCallFunc* f = (TClingCallFunc*) func;
7852 f->Exec(address);
7853}
7854
7855////////////////////////////////////////////////////////////////////////////////
7856
7857void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7858{
7859 TClingCallFunc* f = (TClingCallFunc*) func;
7860 f->Exec(address, &val);
7861}
7862
7863////////////////////////////////////////////////////////////////////////////////
7864
7865void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7866{
7867 TClingCallFunc* f = (TClingCallFunc*) func;
7868 f->ExecWithReturn(address, ret);
7869}
7870
7871////////////////////////////////////////////////////////////////////////////////
7872
7873void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7874 const void* args[] /*=0*/,
7875 int nargs /*=0*/,
7876 void* ret/*=0*/) const
7877{
7878 TClingCallFunc* f = (TClingCallFunc*) func;
7879 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7880}
7881
7882////////////////////////////////////////////////////////////////////////////////
7883
7884Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7885{
7886 TClingCallFunc* f = (TClingCallFunc*) func;
7887 return f->ExecInt(address);
7888}
7889
7890////////////////////////////////////////////////////////////////////////////////
7891
7892Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7893{
7894 TClingCallFunc* f = (TClingCallFunc*) func;
7895 return f->ExecInt64(address);
7896}
7897
7898////////////////////////////////////////////////////////////////////////////////
7899
7900Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7901{
7902 TClingCallFunc* f = (TClingCallFunc*) func;
7903 return f->ExecDouble(address);
7904}
7905
7906////////////////////////////////////////////////////////////////////////////////
7907
7908CallFunc_t* TCling::CallFunc_Factory() const
7909{
7911 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915
7916CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7917{
7918 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7919}
7920
7921////////////////////////////////////////////////////////////////////////////////
7922
7923MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7924{
7925 TClingCallFunc* f = (TClingCallFunc*) func;
7926 return (MethodInfo_t*) f->FactoryMethod();
7927}
7928
7929////////////////////////////////////////////////////////////////////////////////
7930
7931void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7932{
7933 TClingCallFunc* f = (TClingCallFunc*) func;
7934 f->IgnoreExtraArgs(ignore);
7935}
7936
7937////////////////////////////////////////////////////////////////////////////////
7938
7939void TCling::CallFunc_Init(CallFunc_t* func) const
7940{
7942 TClingCallFunc* f = (TClingCallFunc*) func;
7943 f->Init();
7944}
7945
7946////////////////////////////////////////////////////////////////////////////////
7947
7948bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7949{
7950 TClingCallFunc* f = (TClingCallFunc*) func;
7951 return f->IsValid();
7952}
7953
7954////////////////////////////////////////////////////////////////////////////////
7955
7957TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7958{
7959 TClingCallFunc* f = (TClingCallFunc*) func;
7960 return f->IFacePtr();
7961}
7962
7963////////////////////////////////////////////////////////////////////////////////
7964
7965void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7966{
7967 TClingCallFunc* f = (TClingCallFunc*) func;
7968 f->ResetArg();
7969}
7970
7971////////////////////////////////////////////////////////////////////////////////
7972
7973void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7974{
7975 TClingCallFunc* f = (TClingCallFunc*) func;
7976 f->SetArg(param);
7977}
7978
7979////////////////////////////////////////////////////////////////////////////////
7980
7981void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7982{
7983 TClingCallFunc* f = (TClingCallFunc*) func;
7984 f->SetArg(param);
7985}
7986
7987////////////////////////////////////////////////////////////////////////////////
7988
7989void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7990{
7991 TClingCallFunc* f = (TClingCallFunc*) func;
7992 f->SetArg(param);
7993}
7994
7995////////////////////////////////////////////////////////////////////////////////
7996
7997void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7998{
7999 TClingCallFunc* f = (TClingCallFunc*) func;
8000 f->SetArg(param);
8001}
8002
8003////////////////////////////////////////////////////////////////////////////////
8004
8005void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8006{
8007 TClingCallFunc* f = (TClingCallFunc*) func;
8008 f->SetArg(param);
8009}
8010
8011////////////////////////////////////////////////////////////////////////////////
8012
8013void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8014{
8015 TClingCallFunc* f = (TClingCallFunc*) func;
8016 f->SetArg(param);
8017}
8018
8019////////////////////////////////////////////////////////////////////////////////
8020
8021void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8022{
8023 TClingCallFunc* f = (TClingCallFunc*) func;
8024 f->SetArgArray(paramArr, nparam);
8025}
8026
8027////////////////////////////////////////////////////////////////////////////////
8028
8029void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8030{
8031 TClingCallFunc* f = (TClingCallFunc*) func;
8032 f->SetArgs(param);
8033}
8034
8035////////////////////////////////////////////////////////////////////////////////
8036
8037void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8038{
8039 TClingCallFunc* f = (TClingCallFunc*) func;
8040 TClingClassInfo* ci = (TClingClassInfo*) info;
8041 f->SetFunc(ci, method, params, offset);
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045
8046void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8047{
8048 TClingCallFunc* f = (TClingCallFunc*) func;
8049 TClingClassInfo* ci = (TClingClassInfo*) info;
8050 f->SetFunc(ci, method, params, objectIsConst, offset);
8051}
8052////////////////////////////////////////////////////////////////////////////////
8053
8054void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8055{
8056 TClingCallFunc* f = (TClingCallFunc*) func;
8057 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8058 f->SetFunc(minfo);
8059}
8060
8061////////////////////////////////////////////////////////////////////////////////
8062/// Interface to cling function
8063
8064void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8065{
8066 TClingCallFunc* f = (TClingCallFunc*) func;
8067 TClingClassInfo* ci = (TClingClassInfo*) info;
8068 f->SetFuncProto(ci, method, proto, offset, mode);
8069}
8070
8071////////////////////////////////////////////////////////////////////////////////
8072/// Interface to cling function
8073
8074void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8075{
8076 TClingCallFunc* f = (TClingCallFunc*) func;
8077 TClingClassInfo* ci = (TClingClassInfo*) info;
8078 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8079}
8080
8081////////////////////////////////////////////////////////////////////////////////
8082/// Interface to cling function
8083
8084void 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
8085{
8086 TClingCallFunc* f = (TClingCallFunc*) func;
8087 TClingClassInfo* ci = (TClingClassInfo*) info;
8088 llvm::SmallVector<clang::QualType, 4> funcProto;
8089 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8090 iter != end; ++iter) {
8091 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8092 }
8093 f->SetFuncProto(ci, method, funcProto, offset, mode);
8094}
8095
8096////////////////////////////////////////////////////////////////////////////////
8097/// Interface to cling function
8098
8099void 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
8100{
8101 TClingCallFunc* f = (TClingCallFunc*) func;
8102 TClingClassInfo* ci = (TClingClassInfo*) info;
8103 llvm::SmallVector<clang::QualType, 4> funcProto;
8104 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8105 iter != end; ++iter) {
8106 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8107 }
8108 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8109}
8110
8111std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8112{
8113 TClingCallFunc *f = (TClingCallFunc *)func;
8114 std::string wrapper_name;
8115 std::string wrapper;
8116 f->get_wrapper_code(wrapper_name, wrapper);
8117 return wrapper;
8118}
8119
8120//______________________________________________________________________________
8121//
8122// ClassInfo interface
8123//
8124
8125////////////////////////////////////////////////////////////////////////////////
8126/// Return true if the entity pointed to by 'declid' is declared in
8127/// the context described by 'info'. If info is null, look into the
8128/// global scope (translation unit scope).
8129
8130Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8131{
8132 if (!declid)
8133 return kFALSE;
8134
8135 const clang::DeclContext *ctxt = nullptr;
8136 if (info) {
8137 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8138 } else {
8139 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8140 }
8141 if (!ctxt)
8142 return kFALSE;
8143
8144 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8145 if (!decl)
8146 return kFALSE;
8147
8148 const clang::DeclContext *declDC = decl->getDeclContext();
8149 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8150 while (true) {
8151 if (declDC->isTransparentContext()) {
8152 declDC = declDC->getParent();
8153 continue;
8154 }
8155 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8156 if (declRD->isAnonymousStructOrUnion()) {
8157 declDC = declRD->getParent();
8158 continue;
8159 }
8160 }
8161 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8162 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8163 declDC = declNS->getParent();
8164 continue;
8165 }
8166 }
8167 break;
8168 }
8169
8170 return declDC->Equals(ctxt);
8171}
8172
8173////////////////////////////////////////////////////////////////////////////////
8174
8176{
8177 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8178 return TClinginfo->ClassProperty();
8179}
8180
8181////////////////////////////////////////////////////////////////////////////////
8182
8183void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8184{
8185 delete (TClingClassInfo*) cinfo;
8186}
8187
8188////////////////////////////////////////////////////////////////////////////////
8189
8190void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8191{
8192 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8193 TClinginfo->Delete(arena,*fNormalizedCtxt);
8194}
8195
8196////////////////////////////////////////////////////////////////////////////////
8197
8198void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8199{
8200 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8201 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8202}
8203
8204////////////////////////////////////////////////////////////////////////////////
8205
8206void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8207{
8208 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8209 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8210}
8211
8212////////////////////////////////////////////////////////////////////////////////
8213
8214ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8215{
8217 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8218}
8219
8220////////////////////////////////////////////////////////////////////////////////
8221
8222ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8223{
8224 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8225}
8226
8227////////////////////////////////////////////////////////////////////////////////
8228
8229ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8230{
8232 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8233}
8234
8235ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8236{
8238 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8239}
8240
8241
8242////////////////////////////////////////////////////////////////////////////////
8243
8244int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8245{
8246 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8247 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8248}
8249
8250////////////////////////////////////////////////////////////////////////////////
8251
8252bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8253{
8254 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8256}
8257
8258////////////////////////////////////////////////////////////////////////////////
8259
8260bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8261{
8262 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8263 return TClinginfo->HasMethod(name);
8264}
8265
8266////////////////////////////////////////////////////////////////////////////////
8267
8268void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8269{
8271 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8272 TClinginfo->Init(name);
8273}
8274
8275////////////////////////////////////////////////////////////////////////////////
8276
8277void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8278{
8280 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8281 TClinginfo->Init(tagnum);
8282}
8283
8284////////////////////////////////////////////////////////////////////////////////
8285
8286bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8287{
8288 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8289 return TClinginfo->IsBase(name);
8290}
8291
8292////////////////////////////////////////////////////////////////////////////////
8293
8294bool TCling::ClassInfo_IsEnum(const char* name) const
8295{
8297}
8298
8299////////////////////////////////////////////////////////////////////////////////
8300
8302{
8303 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8304 return TClinginfo->IsScopedEnum();
8305}
8306
8307
8308////////////////////////////////////////////////////////////////////////////////
8309
8310EDataType TCling::ClassInfo_GetUnderlyingType(ClassInfo_t* info) const
8311{
8312 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8313 return TClinginfo->GetUnderlyingType();
8314}
8315
8316
8317////////////////////////////////////////////////////////////////////////////////
8318
8319bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8320{
8321 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8322 return TClinginfo->IsLoaded();
8323}
8324
8325////////////////////////////////////////////////////////////////////////////////
8326
8327bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8328{
8329 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8330 return TClinginfo->IsValid();
8331}
8332
8333////////////////////////////////////////////////////////////////////////////////
8334
8335bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8336{
8337 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8338 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8339}
8340
8341////////////////////////////////////////////////////////////////////////////////
8342
8343bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8344{
8345 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8346 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8347}
8348
8349////////////////////////////////////////////////////////////////////////////////
8350
8351int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8352{
8353 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8354 return TClinginfo->Next();
8355}
8356
8357////////////////////////////////////////////////////////////////////////////////
8358
8359void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8360{
8361 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8362 return TClinginfo->New(*fNormalizedCtxt);
8363}
8364
8365////////////////////////////////////////////////////////////////////////////////
8366
8367void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8368{
8369 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8370 return TClinginfo->New(n,*fNormalizedCtxt);
8371}
8372
8373////////////////////////////////////////////////////////////////////////////////
8374
8375void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8376{
8377 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8378 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8379}
8380
8381////////////////////////////////////////////////////////////////////////////////
8382
8383void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8384{
8385 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8386 return TClinginfo->New(arena,*fNormalizedCtxt);
8387}
8388
8389////////////////////////////////////////////////////////////////////////////////
8390
8391Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8392{
8393 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8394 return TClinginfo->Property();
8395}
8396
8397////////////////////////////////////////////////////////////////////////////////
8398
8399int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8400{
8401 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8402 return TClinginfo->Size();
8403}
8404
8405////////////////////////////////////////////////////////////////////////////////
8406
8407Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8408{
8409 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8410 return TClinginfo->Tagnum();
8411}
8412
8413////////////////////////////////////////////////////////////////////////////////
8414
8415const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8416{
8417 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8418 return TClinginfo->FileName();
8419}
8420
8421////////////////////////////////////////////////////////////////////////////////
8422
8423const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8424{
8425 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8426 TTHREAD_TLS_DECL(std::string,output);
8427 TClinginfo->FullName(output,*fNormalizedCtxt);
8428 return output.c_str(); // NOLINT
8429}
8430
8431////////////////////////////////////////////////////////////////////////////////
8432
8433const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8434{
8435 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8436 return TClinginfo->Name();
8437}
8438
8439////////////////////////////////////////////////////////////////////////////////
8440
8441const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8442{
8443 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8444 return TClinginfo->Title();
8445}
8446
8447////////////////////////////////////////////////////////////////////////////////
8448
8449const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8450{
8451 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8452 return TClinginfo->TmpltName();
8453}
8454
8455
8456
8457//______________________________________________________________________________
8458//
8459// BaseClassInfo interface
8460//
8461
8462////////////////////////////////////////////////////////////////////////////////
8463
8464void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8465{
8466 delete(TClingBaseClassInfo*) bcinfo;
8467}
8468
8469////////////////////////////////////////////////////////////////////////////////
8470
8471BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8472{
8474 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8475 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8476}
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8480BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8481 ClassInfo_t* base) const
8482{
8484 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8485 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8486 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8487}
8488
8489////////////////////////////////////////////////////////////////////////////////
8490
8491int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8492{
8493 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8494 return TClinginfo->Next();
8495}
8496
8497////////////////////////////////////////////////////////////////////////////////
8498
8499int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8500{
8501 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8502 return TClinginfo->Next(onlyDirect);
8503}
8504
8505////////////////////////////////////////////////////////////////////////////////
8506
8507Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8508{
8509 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8510 return TClinginfo->Offset(address, isDerivedObject);
8511}
8512
8513////////////////////////////////////////////////////////////////////////////////
8514
8515Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8516{
8517 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8518 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8519 // Offset to the class itself.
8520 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8521 return 0;
8522 }
8523 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8524}
8525
8526////////////////////////////////////////////////////////////////////////////////
8527
8528Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8529{
8530 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8531 return TClinginfo->Property();
8532}
8533
8534////////////////////////////////////////////////////////////////////////////////
8535
8536ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8537{
8538 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8539 return (ClassInfo_t *)TClinginfo->GetBase();
8540}
8541
8542////////////////////////////////////////////////////////////////////////////////
8543
8544Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8545{
8546 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8547 return TClinginfo->Tagnum();
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551
8552const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8553{
8554 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8555 TTHREAD_TLS_DECL(std::string,output);
8556 TClinginfo->FullName(output,*fNormalizedCtxt);
8557 return output.c_str(); // NOLINT
8558}
8559
8560////////////////////////////////////////////////////////////////////////////////
8561
8562const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8563{
8564 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8565 return TClinginfo->Name();
8566}
8567
8568////////////////////////////////////////////////////////////////////////////////
8569
8570const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8571{
8572 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8573 return TClinginfo->TmpltName();
8574}
8575
8576//______________________________________________________________________________
8577//
8578// DataMemberInfo interface
8579//
8580
8581////////////////////////////////////////////////////////////////////////////////
8582
8583int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8584{
8585 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8586 return TClinginfo->ArrayDim();
8587}
8588
8589////////////////////////////////////////////////////////////////////////////////
8590
8591void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8592{
8593 delete(TClingDataMemberInfo*) dminfo;
8594}
8595
8596////////////////////////////////////////////////////////////////////////////////
8597
8598DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8599{
8601 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8602 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8603}
8604
8605////////////////////////////////////////////////////////////////////////////////
8606
8607DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8608{
8610 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8611 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8612 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8613}
8614
8615////////////////////////////////////////////////////////////////////////////////
8616
8617DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8618{
8619 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8620 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8621}
8622
8623////////////////////////////////////////////////////////////////////////////////
8624
8625bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8626{
8627 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8628 return TClinginfo->IsValid();
8629}
8630
8631////////////////////////////////////////////////////////////////////////////////
8632
8633int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8634{
8635 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8636 return TClinginfo->MaxIndex(dim);
8637}
8638
8639////////////////////////////////////////////////////////////////////////////////
8640
8641int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8642{
8643 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8644 return TClinginfo->Next();
8645}
8646
8647////////////////////////////////////////////////////////////////////////////////
8648
8649Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8650{
8651 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8652 return TClinginfo->Offset();
8653}
8654
8655////////////////////////////////////////////////////////////////////////////////
8656
8657Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8658{
8659 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8660 return TClinginfo->Property();
8661}
8662
8663////////////////////////////////////////////////////////////////////////////////
8664
8665Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8666{
8667 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8668 return TClinginfo->TypeProperty();
8669}
8670
8671////////////////////////////////////////////////////////////////////////////////
8672
8673int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8674{
8675 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8676 return TClinginfo->TypeSize();
8677}
8678
8679////////////////////////////////////////////////////////////////////////////////
8680
8681const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8682{
8683 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8684 return TClinginfo->TypeName();
8685}
8686
8687////////////////////////////////////////////////////////////////////////////////
8688
8689const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8690{
8691 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8692 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8693}
8694
8695////////////////////////////////////////////////////////////////////////////////
8696
8697const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8698{
8699 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8700 return TClinginfo->Name();
8701}
8702
8703////////////////////////////////////////////////////////////////////////////////
8704
8705const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8706{
8707 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8708 return TClinginfo->Title();
8709}
8710
8711////////////////////////////////////////////////////////////////////////////////
8712
8713const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8714{
8715 TTHREAD_TLS_DECL(std::string,result);
8716
8717 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8718 result = TClinginfo->ValidArrayIndex().str();
8719 return result.c_str(); // NOLINT
8720}
8721
8722////////////////////////////////////////////////////////////////////////////////
8723
8724void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8725{
8726 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8727 ASTContext &C = decl->getASTContext();
8728 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8729}
8730
8731//______________________________________________________________________________
8732//
8733// Function Template interface
8734//
8735
8736////////////////////////////////////////////////////////////////////////////////
8737
8738static void ConstructorName(std::string &name, const clang::Decl *decl,
8739 cling::Interpreter &interp,
8740 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8741{
8742 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8743 if (!td) return;
8744
8745 clang::QualType qualType(td->getTypeForDecl(),0);
8746 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8747 unsigned int level = 0;
8748 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8749 if (name[cursor] == '>') ++level;
8750 else if (name[cursor] == '<' && level) --level;
8751 else if (level == 0 && name[cursor] == ':') {
8752 name.erase(0,cursor+1);
8753 break;
8754 }
8755 }
8756}
8757
8758////////////////////////////////////////////////////////////////////////////////
8759
8760void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8761{
8762 output.clear();
8763
8764 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8765 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8766 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8767 }
8768 if (!FD) {
8769 Error("GetFunctionName", "NULL Decl!");
8770 return;
8771 }
8772
8773 // For using-decls, show "Derived", not "Base", i.e. use the
8774 // name of the decl context of the UsingShadowDecl (aka `decl`)
8775 // not the name of FD's decl context.
8776 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8777 {
8779
8780 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8781 {
8783 output.insert(output.begin(), '~');
8784 } else {
8785 llvm::raw_string_ostream stream(output);
8786 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8787 // Don't trigger fopen of the source file to count lines:
8788 printPolicy.AnonymousTagLocations = false;
8789 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8790 }
8791}
8792
8793////////////////////////////////////////////////////////////////////////////////
8794/// Return a unique identifier of the declaration represented by the
8795/// FuncTempInfo
8796
8798{
8799 return (DeclId_t)info;
8800}
8801
8802////////////////////////////////////////////////////////////////////////////////
8803/// Delete the FuncTempInfo_t
8804
8805void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8806{
8807 // Currently the address of ft_info is actually the decl itself,
8808 // so we have nothing to do.
8809}
8810
8811////////////////////////////////////////////////////////////////////////////////
8812/// Construct a FuncTempInfo_t
8813
8814FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8815{
8816 // Currently the address of ft_info is actually the decl itself,
8817 // so we have nothing to do.
8818
8819 return (FuncTempInfo_t*)const_cast<void*>(declid);
8820}
8821
8822////////////////////////////////////////////////////////////////////////////////
8823/// Construct a FuncTempInfo_t
8824
8825FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8826{
8827 // Currently the address of ft_info is actually the decl itself,
8828 // so we have nothing to do.
8829
8830 return (FuncTempInfo_t*)ft_info;
8831}
8832
8833////////////////////////////////////////////////////////////////////////////////
8834/// Check validity of a FuncTempInfo_t
8835
8836Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8837{
8838 // Currently the address of ft_info is actually the decl itself,
8839 // so we have nothing to do.
8840
8841 return t_info != nullptr;
8842}
8843
8844////////////////////////////////////////////////////////////////////////////////
8845/// Return the maximum number of template arguments of the
8846/// function template described by ft_info.
8847
8848UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8849{
8850 if (!ft_info) return 0;
8851 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8852 return ft->getTemplateParameters()->size();
8853}
8854
8855////////////////////////////////////////////////////////////////////////////////
8856/// Return the number of required template arguments of the
8857/// function template described by ft_info.
8858
8859UInt_t TCling::FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *ft_info) const
8860{
8861 if (!ft_info) return 0;
8862 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8863 return ft->getTemplateParameters()->getMinRequiredArguments();
8864}
8865
8866////////////////////////////////////////////////////////////////////////////////
8867/// Return the property of the function template.
8868
8869Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8870{
8871 if (!ft_info) return 0;
8872
8873 long property = 0L;
8874 property |= kIsCompiled;
8875
8876 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8877
8878 switch (ft->getAccess()) {
8879 case clang::AS_public:
8880 property |= kIsPublic;
8881 break;
8882 case clang::AS_protected:
8883 property |= kIsProtected;
8884 break;
8885 case clang::AS_private:
8886 property |= kIsPrivate;
8887 break;
8888 case clang::AS_none:
8889 if (ft->getDeclContext()->isNamespace())
8890 property |= kIsPublic;
8891 break;
8892 default:
8893 // IMPOSSIBLE
8894 assert(false && "Unexpected value for the access property value in Clang");
8895 break;
8896 }
8897
8898 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8899 if (const clang::CXXMethodDecl *md =
8900 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8901 if (md->getMethodQualifiers().hasConst()) {
8902 property |= kIsConstant | kIsConstMethod;
8903 }
8904 if (md->isVirtual()) {
8905 property |= kIsVirtual;
8906 }
8907 if (md->isPure()) {
8908 property |= kIsPureVirtual;
8909 }
8910 if (const clang::CXXConstructorDecl *cd =
8911 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8912 if (cd->isExplicit()) {
8913 property |= kIsExplicit;
8914 }
8915 }
8916 else if (const clang::CXXConversionDecl *cd =
8917 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8918 if (cd->isExplicit()) {
8919 property |= kIsExplicit;
8920 }
8921 }
8922 }
8923 return property;
8924}
8925
8926////////////////////////////////////////////////////////////////////////////////
8927/// Return the property not already defined in Property
8928/// See TDictionary's EFunctionProperty
8929
8930Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8931{
8932 if (!ft_info) return 0;
8933
8934 long property = 0L;
8935 property |= kIsCompiled;
8936
8937 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8938 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8939
8940 if (fd->isOverloadedOperator())
8941 property |= kIsOperator;
8942 if (llvm::isa<clang::CXXConversionDecl>(fd))
8943 property |= kIsConversion;
8944 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8945 property |= kIsConstructor;
8946 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8947 property |= kIsDestructor;
8948 if (fd->isInlined())
8949 property |= kIsInlined;
8950 return property;
8951}
8952
8953////////////////////////////////////////////////////////////////////////////////
8954/// Return the name of this function template.
8955
8956void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8957{
8958 output.Clear();
8959 if (!ft_info) return;
8960 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8961 std::string buf;
8962 GetFunctionName(ft->getTemplatedDecl(), buf);
8963 output = buf;
8964}
8965
8966////////////////////////////////////////////////////////////////////////////////
8967/// Return the comments associates with this function template.
8968
8969void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8970{
8971 output.Clear();
8972 if (!ft_info) return;
8973 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8974
8975 // Iterate over the redeclarations, we can have multiple definitions in the
8976 // redecl chain (came from merging of pcms).
8977 if (const RedeclarableTemplateDecl *AnnotFD
8978 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8979 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8980 output = A->getAnnotation().str();
8981 return;
8982 }
8983 }
8984 if (!ft->isFromASTFile()) {
8985 // Try to get the comment from the header file if present
8986 // but not for decls from AST file, where rootcling would have
8987 // created an annotation
8989 }
8990}
8991
8992
8993//______________________________________________________________________________
8994//
8995// MethodInfo interface
8996//
8997
8998////////////////////////////////////////////////////////////////////////////////
8999/// Interface to cling function
9000
9001void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9002{
9003 delete(TClingMethodInfo*) minfo;
9004}
9005
9006////////////////////////////////////////////////////////////////////////////////
9007
9008void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9009{
9010 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9011 // The next call locks the interpreter mutex.
9012 info->CreateSignature(signature);
9013}
9014
9015////////////////////////////////////////////////////////////////////////////////
9016
9017MethodInfo_t* TCling::MethodInfo_Factory() const
9018{
9020 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9021}
9022
9023////////////////////////////////////////////////////////////////////////////////
9024
9025MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9026{
9028 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9029}
9030
9031////////////////////////////////////////////////////////////////////////////////
9032
9033MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9034{
9035 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9037 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9038}
9039
9040////////////////////////////////////////////////////////////////////////////////
9041
9042MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9043{
9044 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9045}
9046
9047////////////////////////////////////////////////////////////////////////////////
9048
9049void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9050{
9051 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9052 // The next call locks the interpreter mutex.
9053 return info->InterfaceMethod();
9054}
9055
9056////////////////////////////////////////////////////////////////////////////////
9057
9058bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9059{
9060 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9061 return info->IsValid();
9062}
9063
9064////////////////////////////////////////////////////////////////////////////////
9065
9066int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9067{
9068 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9069 return info->NArg();
9070}
9071
9072////////////////////////////////////////////////////////////////////////////////
9073
9074int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9075{
9076 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9077 return info->NDefaultArg();
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081
9082int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9083{
9084 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9085 return info->Next();
9086}
9087
9088////////////////////////////////////////////////////////////////////////////////
9089
9090Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9091{
9092 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9093 // The next call locks the interpreter mutex.
9094 return info->Property();
9095}
9096
9097////////////////////////////////////////////////////////////////////////////////
9098
9100{
9101 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9102 // The next call locks the interpreter mutex.
9103 return info->ExtraProperty();
9104}
9105
9106////////////////////////////////////////////////////////////////////////////////
9107
9108TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9109{
9110 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9111 // The next call locks the interpreter mutex.
9112 return (TypeInfo_t*)info->Type();
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116
9117const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9118{
9119 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9120 TTHREAD_TLS_DECL(TString, mangled_name);
9121 // The next call locks the interpreter mutex.
9122 mangled_name = info->GetMangledName();
9123 return mangled_name;
9124}
9125
9126////////////////////////////////////////////////////////////////////////////////
9127
9128const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9129{
9130 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9131 // The next call locks the interpreter mutex.
9132 return info->GetPrototype();
9133}
9134
9135////////////////////////////////////////////////////////////////////////////////
9136
9137const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9138{
9139 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9140 // The next call locks the interpreter mutex.
9141 return info->Name();
9142}
9143
9144////////////////////////////////////////////////////////////////////////////////
9145
9146const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9147{
9148 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9149 // The next call locks the interpreter mutex.
9150 return info->TypeName();
9151}
9152
9153////////////////////////////////////////////////////////////////////////////////
9154
9155std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9156{
9157 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9158 // The next part locks the interpreter mutex.
9159 if (info && info->IsValid())
9160 return info->Type()->NormalizedName(*fNormalizedCtxt);
9161 else
9162 return "";
9163}
9164
9165////////////////////////////////////////////////////////////////////////////////
9166
9167const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9168{
9169 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9170 // The next call locks the interpreter mutex.
9171 return info->Title();
9172}
9173
9174////////////////////////////////////////////////////////////////////////////////
9175
9177{
9178 if (func) {
9179 return MethodInfo_MethodCallReturnType(func->fInfo);
9180 } else {
9181 return EReturnType::kOther;
9182 }
9183}
9184
9185////////////////////////////////////////////////////////////////////////////////
9186
9188{
9189 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9190 if (info && info->IsValid()) {
9191 TClingTypeInfo *typeinfo = info->Type();
9192 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9193 if (QT->isEnumeralType()) {
9194 return EReturnType::kLong;
9195 } else if (QT->isPointerType()) {
9196 // Look for char*
9197 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9198 if ( QT->isCharType() ) {
9199 return EReturnType::kString;
9200 } else {
9201 return EReturnType::kOther;
9202 }
9203 } else if ( QT->isFloatingType() ) {
9204 int sz = typeinfo->Size();
9205 if (sz == 4 || sz == 8) {
9206 // Support only float and double.
9207 return EReturnType::kDouble;
9208 } else {
9209 return EReturnType::kOther;
9210 }
9211 } else if ( QT->isIntegerType() ) {
9212 int sz = typeinfo->Size();
9213 if (sz <= 8) {
9214 // Support only up to long long ... but
9215 // FIXME the TMethodCall::Execute only
9216 // return long (4 bytes) ...
9217 // The v5 implementation of TMethodCall::ReturnType
9218 // was not making the distinction so we let it go
9219 // as is for now, but we really need to upgrade
9220 // TMethodCall::Execute ...
9221 return EReturnType::kLong;
9222 } else {
9223 return EReturnType::kOther;
9224 }
9225 } else {
9226 return EReturnType::kOther;
9227 }
9228 } else {
9229 return EReturnType::kOther;
9230 }
9231}
9232
9233//______________________________________________________________________________
9234//
9235// MethodArgInfo interface
9236//
9237
9238////////////////////////////////////////////////////////////////////////////////
9239
9240void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9241{
9242 delete(TClingMethodArgInfo*) marginfo;
9243}
9244
9245////////////////////////////////////////////////////////////////////////////////
9246
9247MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9248{
9250 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9251}
9252
9253////////////////////////////////////////////////////////////////////////////////
9254
9255MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9256{
9258 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9259}
9260
9261////////////////////////////////////////////////////////////////////////////////
9262
9263MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9264{
9265 return (MethodArgInfo_t*)
9267}
9268
9269////////////////////////////////////////////////////////////////////////////////
9270
9271bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9272{
9273 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9274 return info->IsValid();
9275}
9276
9277////////////////////////////////////////////////////////////////////////////////
9278
9279int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9280{
9281 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9282 return info->Next();
9283}
9284
9285////////////////////////////////////////////////////////////////////////////////
9286
9287Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9288{
9289 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9290 return info->Property();
9291}
9292
9293////////////////////////////////////////////////////////////////////////////////
9294
9295const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9296{
9297 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9298 return info->DefaultValue();
9299}
9300
9301////////////////////////////////////////////////////////////////////////////////
9302
9303const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9304{
9305 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9306 return info->Name();
9307}
9308
9309////////////////////////////////////////////////////////////////////////////////
9310
9311const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9312{
9313 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9314 return info->TypeName();
9315}
9316
9317////////////////////////////////////////////////////////////////////////////////
9318
9319std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9320{
9321 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9322 return info->Type()->NormalizedName(*fNormalizedCtxt);
9323}
9324
9325////////////////////////////////////////////////////////////////////////////////
9326
9327TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9328{
9329 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9330 return (TypeInfo_t*) info->Type();
9331}
9332
9333//______________________________________________________________________________
9334//
9335// TypeInfo interface
9336//
9337
9338////////////////////////////////////////////////////////////////////////////////
9339
9340void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9341{
9342 delete (TClingTypeInfo*) tinfo;
9343}
9344
9345////////////////////////////////////////////////////////////////////////////////
9346
9347TypeInfo_t* TCling::TypeInfo_Factory() const
9348{
9350 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9351}
9352
9353////////////////////////////////////////////////////////////////////////////////
9354
9355TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9356{
9358 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9359}
9360
9361////////////////////////////////////////////////////////////////////////////////
9362
9363TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9364{
9365 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9366}
9367
9368////////////////////////////////////////////////////////////////////////////////
9369
9370void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9371{
9373 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9374 TClinginfo->Init(name);
9375}
9376
9377////////////////////////////////////////////////////////////////////////////////
9378
9379bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9380{
9381 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9382 return TClinginfo->IsValid();
9383}
9384
9385////////////////////////////////////////////////////////////////////////////////
9386
9387const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9388{
9389 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9390 return TClinginfo->Name();
9391}
9392
9393////////////////////////////////////////////////////////////////////////////////
9394
9395Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9396{
9397 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9398 return TClinginfo->Property();
9399}
9400
9401////////////////////////////////////////////////////////////////////////////////
9402
9403int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9404{
9405 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9406 return TClinginfo->RefType();
9407}
9408
9409////////////////////////////////////////////////////////////////////////////////
9410
9411int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9412{
9413 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9414 return TClinginfo->Size();
9415}
9416
9417////////////////////////////////////////////////////////////////////////////////
9418
9419const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9420{
9421 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9422 return TClinginfo->TrueName(*fNormalizedCtxt);
9423}
9424
9425////////////////////////////////////////////////////////////////////////////////
9426
9427void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9428{
9429 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9430 return TClinginfo->QualTypePtr();
9431}
9432
9433
9434//______________________________________________________________________________
9435//
9436// TypedefInfo interface
9437//
9438
9439////////////////////////////////////////////////////////////////////////////////
9440
9441void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9442{
9443 delete(TClingTypedefInfo*) tinfo;
9444}
9445
9446////////////////////////////////////////////////////////////////////////////////
9447
9448TypedefInfo_t* TCling::TypedefInfo_Factory() const
9449{
9451 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9452}
9453
9454////////////////////////////////////////////////////////////////////////////////
9455
9456TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9457{
9459 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9460}
9461
9462////////////////////////////////////////////////////////////////////////////////
9463
9464TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9465{
9466 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9467}
9468
9469////////////////////////////////////////////////////////////////////////////////
9470
9471void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9472 const char* name) const
9473{
9475 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9476 TClinginfo->Init(name);
9477}
9478
9479////////////////////////////////////////////////////////////////////////////////
9480
9481bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9482{
9483 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9484 return TClinginfo->IsValid();
9485}
9486
9487////////////////////////////////////////////////////////////////////////////////
9488
9489Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9490{
9491 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9492 return TClinginfo->Next();
9493}
9494
9495////////////////////////////////////////////////////////////////////////////////
9496
9497Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9498{
9499 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9500 return TClinginfo->Property();
9501}
9502
9503////////////////////////////////////////////////////////////////////////////////
9504
9505int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9506{
9507 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9508 return TClinginfo->Size();
9509}
9510
9511////////////////////////////////////////////////////////////////////////////////
9512
9513const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9514{
9515 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9516 return TClinginfo->TrueName(*fNormalizedCtxt);
9517}
9518
9519////////////////////////////////////////////////////////////////////////////////
9520
9521const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9522{
9523 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9524 return TClinginfo->Name();
9525}
9526
9527////////////////////////////////////////////////////////////////////////////////
9528
9529const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9530{
9531 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9532 return TClinginfo->Title();
9533}
9534
9535////////////////////////////////////////////////////////////////////////////////
9536
9537bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9538{
9539 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9540 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9541 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9542}
9543
9544////////////////////////////////////////////////////////////////////////////////
9545
9546bool TCling::IsIntegerType(const void * QualTypePtr) const
9547{
9548 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9549 return QT->hasIntegerRepresentation();
9550}
9551
9552////////////////////////////////////////////////////////////////////////////////
9553
9554bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9555{
9556 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9557 return QT->hasSignedIntegerRepresentation();
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561
9562bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9563{
9564 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9565 return QT->hasUnsignedIntegerRepresentation();
9566}
9567
9568////////////////////////////////////////////////////////////////////////////////
9569
9570bool TCling::IsFloatingType(const void * QualTypePtr) const
9571{
9572 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9573 return QT->hasFloatingRepresentation();
9574}
9575
9576////////////////////////////////////////////////////////////////////////////////
9577
9578bool TCling::IsPointerType(const void * QualTypePtr) const
9579{
9580 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9581 return QT->hasPointerRepresentation();
9582}
9583
9584////////////////////////////////////////////////////////////////////////////////
9585
9586bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9587{
9588 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9589 return QT->isVoidPointerType();
9590}
9591
9592////////////////////////////////////////////////////////////////////////////////
9593
9595{
9596 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9597 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9598}
9599
9600////////////////////////////////////////////////////////////////////////////////
9601
9603{
9604 if (!fInitialMutex) {
9605 if (fInitialMutex.fRecurseCount) {
9606 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9607 }
9608 fInitialMutex.fState = mtx->GetStateBefore();
9609 }
9610 // We will "forget" this lock once we backed out of all interpreter frames.
9611 // Here we are entering one, so ++.
9612 ++fInitialMutex.fRecurseCount;
9613}
9614
9615////////////////////////////////////////////////////////////////////////////////
9616
9618{
9619 if (!fInitialMutex)
9620 return;
9621 if (fInitialMutex.fRecurseCount == 0) {
9622 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9623 }
9624 else if (--fInitialMutex.fRecurseCount == 0) {
9625 // We have returned from all interpreter frames. Reset the initial lock state.
9626 fInitialMutex.fState.reset();
9627 }
9628}
9629
9630////////////////////////////////////////////////////////////////////////////////
9631/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9632
9634{
9635 if (gInterpreterMutex) {
9636 if (delta) {
9637 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9638 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9639 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9640 // Now that we have the lock, update the global
9641 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9642 std::swap(fInitialMutex, typedDelta->fInitialState);
9643 } else {
9644 // This case happens when EnableThreadSafety is first called from
9645 // the interpreter function we just handled.
9646 // Since thread safety was not enabled at the time we rewound, there was
9647 // no lock taken and even-though we should be locking the rest of this
9648 // interpreter handling/modifying code (since there might be threads in
9649 // flight), we can't because there would not be any lock guard to release the
9650 // locks
9651 if (fInitialMutex || fInitialMutex.fRecurseCount !=0)
9652 Error("ApplyToInterpreterMutex",
9653 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9654 "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.");
9655 }
9656 }
9657}
9658
9659////////////////////////////////////////////////////////////////////////////////
9660/// Reset the interpreter lock to the state it had before interpreter-related
9661/// calls happened.
9662
9664{
9665 if (fInitialMutex) {
9666 // Need to start a new recurse count.
9667 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9668 std::swap(uniqueP->fInitialState, fInitialMutex);
9669 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9670 return uniqueP.release();
9671 }
9672 R__ASSERT(fInitialMutex.fRecurseCount == 0);
9673 return nullptr;
9674}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
true
Register systematic variations for multiple existing columns using auto-generated tags.
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
RooAbsReal & function()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
int Ssiz_t
Definition RtypesCore.h:67
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1308
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7249
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:6996
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:574
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:901
externint optind
Definition TCling.cxx:317
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:368
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:569
TListOfDataMembers & LODM
Definition TCling.cxx:6898
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:557
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:333
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:224
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3909
bool TCling__LibraryLoadingFailed(const std::string &errmessage, const std::string &libStem, bool permanent, bool resolved)
Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name, which is extracted by er...
Definition TCling.cxx:351
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1951
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3133
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1089
bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname, std::string &result)
Try hard to avoid looking up in the Cling database as this could enduce an unwanted autoparsing.
Definition TCling.cxx:910
static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName=nullptr)
Checks if there is an ASTFile on disk for the given module M.
Definition TCling.cxx:1074
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:379
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:633
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:3951
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1674
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:628
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:221
int TCling_GenerateDictionary(const std::vector< std::string > &classes, const std::vector< std::string > &headers, const std::vector< std::string > &fwdDecls, const std::vector< std::string > &unknown)
Definition TCling.cxx:699
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1088
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:251
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:593
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:564
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:604
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3927
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:588
return
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6896
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:389
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:215
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:644
TListOfEnums & LOE
Definition TCling.cxx:6901
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:360
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:233
TListOfFunctions & LOF
Definition TCling.cxx:6899
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:623
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1039
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1192
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8738
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:326
static int HandleInterpreterException(cling::MetaProcessor *metaProcessor, const char *input_line, cling::Interpreter::CompilationResult &compRes, cling::Value *result)
Let cling process a command line.
Definition TCling.cxx:2436
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:7158
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:236
static clang::ClassTemplateDecl * FindTemplateInNamespace(clang::Decl *decl)
Find a template decl within N nested namespaces, 0<=N<inf Assumes 1 and only 1 template present and 1...
Definition TCling.cxx:680
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1976
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:608
const char * fantomline
Definition TCling.cxx:848
TListOfFunctionTemplates & LOFT
Definition TCling.cxx:6900
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:583
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6336
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5516
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:218
if(isa< VarDecl >(D)||isa< FieldDecl >(D)||isa< EnumConstantDecl >(D))
Definition TCling.cxx:6903
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:600
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program.
Definition TCling.cxx:1061
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:639
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:616
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7270
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:651
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
@ kIsNotReacheable
Definition TDictionary.h:87
#define gDirectory
Definition TDirectory.h:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
externInt_t gErrorIgnoreLevel
Definition TError.h:127
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
Int_t i
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:622
#define gROOT
Definition TROOT.h:414
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
R__EXTERN TSystem * gSystem
Definition TSystem.h:566
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17536
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
virtual std::unique_ptr< State > GetStateBefore()=0
Storage_t const & get() const
Const access to the underlying stl container.
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
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 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:3466
EState GetState() const
Definition TClass.h:488
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2887
@ kLoading
Definition TClass.h:332
@ kUnloading
Definition TClass.h:332
EState fState
cached of the streaming method to use
Definition TClass.h:277
std::atomic< TList * > fBase
Definition TClass.h:201
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3825
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:4942
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:2206
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3425
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5989
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5776
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5731
TObjArray * fStreamerInfo
Definition TClass.h:198
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5942
ClassInfo_t * GetClassInfo() const
Definition TClass.h:433
ClassInfo_t * fClassInfo
Definition TClass.h:222
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2898
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4242
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6116
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1821
@ kInterpreted
Definition TClass.h:126
@ kHasTClassInit
Definition TClass.h:127
@ kEmulated
Definition TClass.h:125
@ kForwardDeclared
Definition TClass.h:124
@ kNamespaceForMeta
Definition TClass.h:131
Version_t GetClassVersion() const
Definition TClass.h:420
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:259
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3490
@ kIsTObject
Definition TClass.h:100
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2969
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 SetArgs(const char *args)
Longptr_t ExecInt(void *address)
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
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() const
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1015
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1023
std::hash< std::string > fHashFunc
Definition TCling.h:621
std::set< size_t > fLinesHashSet
Definition TCling.h:620
std::string fContent
Definition TCling.h:619
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6208
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9295
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8301
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9387
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9049
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4399
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3889
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9481
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6269
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7939
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:3652
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6572
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7454
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7865
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9108
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7842
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:7497
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3728
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8724
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:496
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9090
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4446
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8335
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8657
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7582
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:4493
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3773
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8327
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6765
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9403
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4375
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8214
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9137
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8471
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7512
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7286
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9187
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7713
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3564
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9058
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8814
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9347
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7551
void InvalidateGlobal(const clang::Decl *D)
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7675
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7660
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3352
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9529
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:8064
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5659
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:6527
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9594
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1823
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4511
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1628
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7766
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2661
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8491
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6639
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7916
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7900
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7965
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5467
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3176
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3876
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7931
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9633
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6595
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:4727
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:8130
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3142
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:7476
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8583
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9327
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8617
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3669
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:5532
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8351
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7603
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9271
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9411
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3787
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7484
TCling(const char *name, const char *title, const char *const argv[], void *interpLibHandle)
Initialize the cling interpreter interface.
Definition TCling.cxx:1346
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7639
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:8848
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:5159
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9448
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9586
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2466
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8399
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9311
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:644
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5407
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8641
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9521
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8464
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9099
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3556
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7092
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8825
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8633
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8836
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:2675
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8286
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3687
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8681
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4954
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8021
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8111
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9663
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9303
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3151
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9471
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8705
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7884
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3089
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:7533
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:7353
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7923
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9562
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9464
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:5052
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:2406
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9319
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:4836
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9287
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9505
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7873
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:5204
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:634
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6745
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3519
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9489
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:5011
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9370
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7593
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8673
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8441
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8697
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5482
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9554
void ForgetMutexState() final
Definition TCling.cxx:9617
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9082
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8175
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9001
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9240
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8598
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8206
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:6114
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6002
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8268
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8536
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7892
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8391
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8515
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:421
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5389
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7339
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7416
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6951
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8869
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9419
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6020
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7686
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6989
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9279
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9602
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9395
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9128
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:8859
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:2023
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6160
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9008
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4353
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6974
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:2397
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8625
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8294
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9074
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4502
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5929
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:7612
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9117
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9546
std::hash< std::string > fStringHashFunction
Definition TCling.h:124
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:591
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5114
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8359
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7407
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8760
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4527
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7398
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9263
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8507
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:4181
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7445
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3419
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9340
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9066
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4945
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9176
void ProcessClassesToUpdate()
Definition TCling.cxx:1992
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:5137
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:4966
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9167
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8570
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:3102
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8552
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8029
int UnloadFile(const char *path) const final
Definition TCling.cxx:7645
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4045
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7849
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9578
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9570
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8930
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7948
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8562
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8713
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4548
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1032
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4876
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5237
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8319
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8407
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8528
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8037
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4482
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8415
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8969
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8449
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3863
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1707
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6631
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:3744
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7667
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:3758
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7520
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3589
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5941
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3896
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8591
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:5420
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:4520
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:2697
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6082
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9042
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7957
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9247
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6739
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:5033
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8183
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8310
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8805
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:5181
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3802
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8649
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7908
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9017
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8665
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3081
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2455
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:7543
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2371
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9441
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3712
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9513
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7564
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8423
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:6385
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9146
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7973
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7367
void UpdateListsOnUnloaded(const cling::Transaction &T)
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6681
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9537
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1646
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:8244
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:4775
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:8956
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9379
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1918
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9155
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8433
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4558
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8252
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3125
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9363
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9427
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8260
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8198
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:8689
virtual void ShutDown() final
Definition TCling.cxx:1665
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3903
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9497
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1688
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:3573
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:4993
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6754
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5745
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8544
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6981
Collection abstract base class.
Definition TCollection.h:65
virtual void Add(TObject *obj)=0
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:212
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h:63
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:175
DeclId_t GetDeclId() const
Definition TEnum.cxx:146
@ kNone
Definition TEnum.h:48
@ kAutoload
Definition TEnum.h:49
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:53
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
void Clear(Option_t *option="") override
Remove all objects 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.
int(* AutoLoadCallBack_t)(const char *)
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
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...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:83
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:307
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.
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
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:196
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual TClass * IsA() const
Definition TObject.h:240
void MakeZombie()
Definition TObject.h:53
TObject()
TObject constructor.
Definition TObject.h:251
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:3070
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2790
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2980
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3080
static const char **& GetExtraInterpreterArgs()
INTERNAL function!
Definition TROOT.cxx:2990
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3059
Sequenceable collection abstract base class.
Int_t LastIndex() const
void Add(TObject *obj) override
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:931
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:572
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
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 I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:188
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:183
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:184
std::string InsertStd(const char *tname)
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h:208
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
constexpr Double_t C()
Velocity of light in .
Definition TMath.h:114
constexpr Double_t E()
Base of natural log: .
Definition TMath.h:93
#define R__DLLEXPORT
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:135
Long_t fMemVirtual
Definition TSystem.h:204
Long_t fMemResident
Definition TSystem.h:203
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.
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()