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" {
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"
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load a library.
332
333extern "C" int TCling__LoadLibrary(const char *library)
334{
335 return gSystem->Load(library, "", false);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
340
341extern "C" void TCling__RestoreInterpreterMutex(void *delta)
342{
343 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
348/// which is extracted by error messages we get from callback from cling. Return true
349/// when the missing library was autoloaded.
350
351extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
352{
353 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Reset the interpreter lock to the state it had before interpreter-related
358/// calls happened.
359
361{
362 return ((TCling*)gCling)->RewindInterpreterMutex();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Lock the interpreter.
367
369{
370 if (gInterpreterMutex) {
372 }
373 return nullptr;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Unlock the interpreter.
378
380{
381 if (gInterpreterMutex) {
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
388
390{
391 static Bool_t entered = kFALSE;
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
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);
452 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
453 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
454 } else {
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
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);
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
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());
760 while (dirbase.Length() && dirbase != "."
761 && dirbase != "include" && dirbase != "inc"
762 && dirbase != "prec_stl") {
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
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());
814 }
815 //(3) checking if we can compile a macro, if not then cleaning
817 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
818 Int_t ret = gSystem->CompileMacro(fileName, "k");
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);
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
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
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)
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
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];
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
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());
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)
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)
1084
1085 return !ModuleFileName.empty();
1086}
1087
1088static bool HaveFullGlobalModuleIndex = false;
1090{
1091 CompilerInstance &CI = *interp.getCI();
1092 Preprocessor &PP = CI.getPreprocessor();
1093 auto ModuleManager = CI.getASTReader();
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.
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.
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) {
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 }
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();
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(),
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
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"};
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
1246
1247 GlobalModuleIndex *GlobalIndex = nullptr;
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;
1266 continue;
1267
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 }
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
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()) {
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()) {
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.
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()){
1481 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1482 ModulesCachePath = Env.str();
1483 } else {
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(),
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.
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
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.
1528 } else {
1529 interpArgs.push_back(*extraArgs);
1530 }
1531 }
1532
1533 std::vector<std::string> _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]),
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
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>
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{
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.
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
1720 if (gDebug > 1)
1721 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1722
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)) {
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
1749 if (!nsTClassEntry) {
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).
1758 } else {
1759 // namespaces can have enums added to them
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
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
1824{
1827 assert(!pcmFileNameFullPath.empty());
1828 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1829
1830 // Easier to work with the ROOT interfaces.
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))
1849
1851 if (pendingRdict != fPendingRdicts.end()) {
1852 llvm::StringRef pcmContent = pendingRdict->second;
1854 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1856
1857 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
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");
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.
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];
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
2024 const char** headers,
2025 const char** includePaths,
2026 const char* payloadCode,
2027 const char* fwdDeclsCode,
2028 void (*triggerFunc)(),
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);
2044
2045 // Treat Aclic Libs in a special way. Do not delay the parsing.
2047 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
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.");
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!
2065
2066 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2068 }
2069 cling::Transaction* T = nullptr;
2070 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
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())){
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.
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) {
2124 wasDlopened = true;
2125 } else {
2127 }
2128 }
2129 } // if (!lateRegistration)
2130
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 "\"))) "
2178 ++posEnumName;
2179 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2180 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2183 // posEnumNameEnd now points to the last character of the name.
2184
2185 std::string enumName = fwdDeclsLine.substr(posEnumName,
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
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'",
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);
2248 addTemplate = true;
2249 }
2250 size_t theHash = fStringHashFunction(temp);
2251 classesHeader++;
2253 // This is done in order to distinguish headers from files and from the payloadCode
2255 fPayloads.insert(theHash);
2257 }
2258 if (gDebug > 2)
2259 Info("TCling::RegisterModule",
2260 "Adding a header for %s", temp.c_str());
2262 if (addTemplate) {
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(),
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());
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
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
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
2356 // __ROOTCLING__ might be pulled in through PCH
2357 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2358 "#undef __ROOTCLING__\n"
2360 "#endif");
2361 }
2362
2363 if (wasDlopened) {
2365 void* dyLibHandle = fRegisterModuleDyLibs.back();
2366 fRegisterModuleDyLibs.pop_back();
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 //
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)
2498 }
2500 gROOT->SetLineIsProcessing();
2501
2502 struct InterpreterFlagsRAII {
2503 cling::Interpreter* fInterpreter;
2505
2506 InterpreterFlagsRAII(cling::Interpreter* interp):
2507 fInterpreter(interp),
2508 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2509 {
2510 fInterpreter->enableDynamicLookup(true);
2511 }
2513 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2514 gROOT->SetLineHasBeenProcessed();
2515 }
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.
2530 TString arguments;
2531 TString io;
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 }
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 }
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,
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");
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);
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
2698 const TClass* cl, Bool_t isTransient)
2699{
2700 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2701 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
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 if (TClassEdit::IsUniquePtr(cl->GetName())) {
2724 // Ignore error caused by the inside of std::unique_ptr
2725 // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer
2726 // which checks the number of elements in the GetListOfRealData.
2727 // If this usage is removed, this can be replaced with a return statement.
2728 // See https://github.com/root-project/root/issues/13574
2729 isTransient = true;
2730 }
2731
2732 const char* cobj = (const char*) obj; // for ptr arithmetics
2733
2734 // Treat the case of std::complex in a special manner. We want to enforce
2735 // the layout of a stl implementation independent class, which is the
2736 // complex as implemented in ROOT5.
2737
2738 // A simple lambda to simplify the code
2739 auto inspInspect = [&] (ptrdiff_t offset){
2740 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2741 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2742 };
2743
2745 switch(complexType) {
2747 {
2748 break;
2749 }
2751 {
2752 inspInspect(sizeof(float));
2753 return;
2754 }
2756 {
2757 inspInspect(sizeof(double));
2758 return;
2759 }
2761 {
2762 inspInspect(sizeof(int));
2763 return;
2764 }
2766 {
2767 inspInspect(sizeof(long));
2768 return;
2769 }
2770 }
2771
2772 static clang::PrintingPolicy
2773 printPol(fInterpreter->getCI()->getLangOpts());
2774 if (printPol.Indentation) {
2775 // not yet initialized
2776 printPol.Indentation = 0;
2777 printPol.SuppressInitializers = true;
2778 }
2779
2780 const char* clname = cl->GetName();
2781 // Printf("Inspecting class %s\n", clname);
2782
2783 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2784 const clang::Decl *scopeDecl = nullptr;
2785 const clang::Type *recordType = nullptr;
2786
2787 if (cl->GetClassInfo()) {
2789 scopeDecl = clingCI->GetDecl();
2790 recordType = clingCI->GetType();
2791 } else {
2792 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2793 // Diags will complain about private classes:
2794 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2795 &recordType);
2796 }
2797 if (!scopeDecl) {
2798 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2799 return;
2800 }
2801 const clang::CXXRecordDecl* recordDecl
2802 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2803 if (!recordDecl) {
2804 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2805 return;
2806 }
2807
2808 {
2809 // Force possible deserializations first. We need to have no pending
2810 // Transaction when passing control flow to the inspector below (ROOT-7779).
2811 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2812
2813 astContext.getASTRecordLayout(recordDecl);
2814
2815 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2816 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2817 }
2818
2819 const clang::ASTRecordLayout& recLayout
2820 = astContext.getASTRecordLayout(recordDecl);
2821
2822 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2823 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2824 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2825 // cl->GetName());
2826 // }
2827 if (cl->Size() != recLayout.getSize().getQuantity()) {
2828 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2829 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2830 }
2831
2832 unsigned iNField = 0;
2833 // iterate over fields
2834 // FieldDecls are non-static, else it would be a VarDecl.
2835 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2836 eField = recordDecl->field_end(); iField != eField;
2837 ++iField, ++iNField) {
2838
2839
2840 clang::QualType memberQT = iField->getType();
2841 if (recordType) {
2842 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2844 }
2845 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2846 if (memberQT.isNull()) {
2847 std::string memberName;
2848 llvm::raw_string_ostream stream(memberName);
2849 // Don't trigger fopen of the source file to count lines:
2850 printPol.AnonymousTagLocations = false;
2851 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2852 stream.flush();
2853 Error("InspectMembers",
2854 "Cannot retrieve QualType for member %s while inspecting class %s",
2855 memberName.c_str(), clname);
2856 continue; // skip member
2857 }
2858 const clang::Type* memType = memberQT.getTypePtr();
2859 if (!memType) {
2860 std::string memberName;
2861 llvm::raw_string_ostream stream(memberName);
2862 // Don't trigger fopen of the source file to count lines:
2863 printPol.AnonymousTagLocations = false;
2864 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2865 stream.flush();
2866 Error("InspectMembers",
2867 "Cannot retrieve Type for member %s while inspecting class %s",
2868 memberName.c_str(), clname);
2869 continue; // skip member
2870 }
2871
2872 const clang::Type* memNonPtrType = memType;
2873 Bool_t ispointer = false;
2874 if (memNonPtrType->isPointerType()) {
2875 ispointer = true;
2876 clang::QualType ptrQT
2877 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2878 if (recordType) {
2879 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2881 }
2882 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2883 if (ptrQT.isNull()) {
2884 std::string memberName;
2885 llvm::raw_string_ostream stream(memberName);
2886 // Don't trigger fopen of the source file to count lines:
2887 printPol.AnonymousTagLocations = false;
2888 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2889 stream.flush();
2890 Error("InspectMembers",
2891 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2892 memberName.c_str(), clname);
2893 continue; // skip member
2894 }
2895 memNonPtrType = ptrQT.getTypePtr();
2896 }
2897
2898 // assemble array size(s): "[12][4][]"
2899 llvm::SmallString<8> arraySize;
2900 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2901 unsigned arrLevel = 0;
2902 bool haveErrorDueToArray = false;
2903 while (arrType) {
2904 ++arrLevel;
2905 arraySize += '[';
2906 const clang::ConstantArrayType* constArrType =
2907 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2908 if (constArrType) {
2909 constArrType->getSize().toStringUnsigned(arraySize);
2910 }
2911 arraySize += ']';
2912 clang::QualType subArrQT = arrType->getElementType();
2913 if (subArrQT.isNull()) {
2914 std::string memberName;
2915 llvm::raw_string_ostream stream(memberName);
2916 // Don't trigger fopen of the source file to count lines:
2917 printPol.AnonymousTagLocations = false;
2918 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2919 stream.flush();
2920 Error("InspectMembers",
2921 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2922 arrLevel, subArrQT.getAsString(printPol).c_str(),
2923 memberName.c_str(), clname);
2924 haveErrorDueToArray = true;
2925 break;
2926 }
2927 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2928 }
2929 if (haveErrorDueToArray) {
2930 continue; // skip member
2931 }
2932
2933 // construct member name
2934 std::string fieldName;
2935 if (memType->isPointerType()) {
2936 fieldName = "*";
2937 }
2938
2939 // Check if this field has a custom ioname, if not, just use the one of the decl
2940 std::string ioname(iField->getName());
2942 fieldName += ioname;
2943 fieldName += arraySize;
2944
2945 // get member offset
2946 // NOTE currently we do not support bitfield and do not support
2947 // member that are not aligned on 'bit' boundaries.
2948 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2949 ptrdiff_t fieldOffset = offset.getQuantity();
2950
2951 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2952 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2953 // R__insp.InspectMember(fName, "fName.");
2954 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2955
2956 // If the class has a custom streamer and the type of the filed is a
2957 // private enum, struct or class, skip it.
2958 if (!insp.IsTreatingNonAccessibleTypes()){
2959 auto iFiledQtype = iField->getType();
2960 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2961 auto declAccess = tagDecl->getAccess();
2963 continue;
2964 }
2965 }
2966 }
2967
2968 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2969
2970 if (!ispointer) {
2971 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2972 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2973 // nested objects get an extra call to InspectMember
2974 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2975 std::string sFieldRecName;
2978 clang::QualType(memNonPtrType,0),
2979 *fInterpreter,
2981 }
2982
2983 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2984 // if we can not find the member (which should not really happen),
2985 // let's consider it transient.
2986 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2987
2988 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2989 (fieldName + '.').c_str(), transient);
2990
2991 }
2992 }
2993 } // loop over fields
2994
2995 // inspect bases
2996 // TNamed::ShowMembers(R__insp);
2997 unsigned iNBase = 0;
2998 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2999 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3000 iBase != eBase; ++iBase, ++iNBase) {
3001 clang::QualType baseQT = iBase->getType();
3002 if (baseQT.isNull()) {
3003 Error("InspectMembers",
3004 "Cannot find QualType for base number %d while inspecting class %s",
3005 iNBase, clname);
3006 continue;
3007 }
3008 const clang::CXXRecordDecl* baseDecl
3009 = baseQT->getAsCXXRecordDecl();
3010 if (!baseDecl) {
3011 Error("InspectMembers",
3012 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3013 iNBase, clname);
3014 continue;
3015 }
3016 TClass* baseCl=nullptr;
3017 std::string sBaseName;
3018 // Try with the DeclId
3019 std::vector<TClass*> foundClasses;
3021 if (foundClasses.size()==1){
3023 } else {
3024 // Try with the normalised Name, as a fallback
3025 if (!baseCl){
3027 baseQT,
3028 *fInterpreter,
3031 }
3032 }
3033
3034 if (!baseCl){
3035 std::string qualNameForDiag;
3037 Error("InspectMembers",
3038 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3039 continue;
3040 }
3041
3042 int64_t baseOffset;
3043 if (iBase->isVirtual()) {
3044 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
3045 if (!isTransient) {
3046 Error("InspectMembers",
3047 "Base %s of class %s is virtual but no object provided",
3048 sBaseName.c_str(), clname);
3049 }
3051 } else {
3052 // We have an object to determine the vbase offset.
3054 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3055 if (ci && baseCi) {
3056 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3057 true /*isDerivedObj*/);
3058 if (baseOffset == -1) {
3059 Error("InspectMembers",
3060 "Error calculating offset of virtual base %s of class %s",
3061 sBaseName.c_str(), clname);
3062 }
3063 } else {
3064 Error("InspectMembers",
3065 "Cannot calculate offset of virtual base %s of class %s",
3066 sBaseName.c_str(), clname);
3067 continue;
3068 }
3069 }
3070 } else {
3071 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3072 }
3073 // TOFIX: baseCl can be null here!
3074 if (baseCl->IsLoaded()) {
3075 // For loaded class, CallShowMember will (especially for TObject)
3076 // call the virtual ShowMember rather than the class specific version
3077 // resulting in an infinite recursion.
3079 } else {
3080 baseCl->CallShowMembers(cobj + baseOffset,
3081 insp, isTransient);
3082 }
3083 } // loop over bases
3084}
3085
3086////////////////////////////////////////////////////////////////////////////////
3087/// Reset the interpreter internal state in case a previous action was not correctly
3088/// terminated.
3089
3091{
3092 // No-op there is not equivalent state (to be cleared) in Cling.
3093}
3094
3095////////////////////////////////////////////////////////////////////////////////
3096/// Delete existing temporary values.
3097
3099{
3100 // No-op for cling due to cling::Value.
3101}
3102
3103////////////////////////////////////////////////////////////////////////////////
3104/// Declare code to the interpreter, without any of the interpreter actions
3105/// that could trigger a re-interpretation of the code. I.e. make cling
3106/// behave like a compiler: no dynamic lookup, no input wrapping for
3107/// subsequent execution, no automatic provision of declarations but just a
3108/// plain `#include`.
3109/// Returns true on success, false on failure.
3110
3111bool TCling::Declare(const char* code)
3112{
3114
3117
3118 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3119 fInterpreter->enableDynamicLookup(false);
3120 bool oldRawInput = fInterpreter->isRawInputEnabled();
3121 fInterpreter->enableRawInput(true);
3122
3123 Bool_t ret = LoadText(code);
3124
3125 fInterpreter->enableRawInput(oldRawInput);
3126 fInterpreter->enableDynamicLookup(oldDynLookup);
3127 return ret;
3128}
3129
3130////////////////////////////////////////////////////////////////////////////////
3131/// It calls a "fantom" method to synchronize user keyboard input
3132/// and ROOT prompt line.
3133
3138
3139// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3140// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3141// was already taking a lock.
3142static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3143{
3144 // Check shared library.
3147 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3148 return false;
3149}
3150
3156
3157////////////////////////////////////////////////////////////////////////////////
3158/// Return true if ROOT has cxxmodules pcm for a given library name.
3159// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3161{
3162 llvm::StringRef ModuleName(libname);
3163 ModuleName = llvm::sys::path::stem(ModuleName);
3164 ModuleName.consume_front("lib");
3165
3166 // FIXME: In case when the modulemap is not yet loaded we will return the
3167 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3168 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3169 // which may happen after calling this interface. Maybe we should also check
3170 // if there is a Event.pcm file and a module.modulemap, load it and return
3171 // true.
3172 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3173 clang::Module *M = moduleMap.findModule(ModuleName);
3174 return M && !M->IsUnimportable && M->getASTFile();
3175}
3176
3177////////////////////////////////////////////////////////////////////////////////
3178/// Return true if the file has already been loaded by cint.
3179/// We will try in this order:
3180/// actual filename
3181/// filename as a path relative to
3182/// the include path
3183/// the shared library path
3184
3186{
3188
3189 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3190 // cling::DynamicLibraryManager.
3191
3192 std::string file_name = filename;
3193 size_t at = std::string::npos;
3194 while ((at = file_name.find("/./")) != std::string::npos)
3195 file_name.replace(at, 3, "/");
3196
3197 std::string filesStr = "";
3198 llvm::raw_string_ostream filesOS(filesStr);
3199 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3200 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3201 filesOS.flush();
3202
3203 llvm::SmallVector<llvm::StringRef, 100> files;
3204 llvm::StringRef(filesStr).split(files, "\n");
3205
3206 std::set<std::string> fileMap;
3207 llvm::StringRef file_name_ref(file_name);
3208 // Fill fileMap; return early on exact match.
3210 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3211 if ((*iF) == file_name_ref) return kTRUE; // exact match
3212 fileMap.insert(iF->str());
3213 }
3214
3215 if (fileMap.empty()) return kFALSE;
3216
3217 // Check MacroPath.
3218 TString sFilename(file_name.c_str());
3220 && fileMap.count(sFilename.Data())) {
3221 return kTRUE;
3222 }
3223
3224 // Check IncludePath.
3225 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3226 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3227 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3228 while (incPath.Index(" :") != -1) {
3229 incPath.ReplaceAll(" :", ":");
3230 }
3231 incPath.Prepend(".:");
3232 sFilename = file_name.c_str();
3234 && fileMap.count(sFilename.Data())) {
3235 return kTRUE;
3236 }
3237
3238 // Check shared library.
3239 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3240 return kTRUE;
3241
3242 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3243 clang::ConstSearchDirIterator *CurDir = nullptr;
3244 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3245 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3246 auto FE = HS.LookupFile(file_name.c_str(),
3247 clang::SourceLocation(),
3248 /*isAngled*/ false,
3249 /*FromDir*/ nullptr, CurDir,
3250 clang::ArrayRef<std::pair<const clang::FileEntry *,
3251 const clang::DirectoryEntry *>>(),
3252 /*SearchPath*/ nullptr,
3253 /*RelativePath*/ nullptr,
3254 /*RequestingModule*/ nullptr,
3255 /*SuggestedModule*/ nullptr,
3256 /*IsMapped*/ nullptr,
3257 /*IsFrameworkFound*/ nullptr,
3258 /*SkipCache*/ false,
3259 /*BuildSystemModule*/ false,
3260 /*OpenFile*/ false,
3261 /*CacheFail*/ false);
3262 if (FE) {
3263 // check in the source manager if the file is actually loaded
3264 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3265 // this works only with header (and source) files...
3266 clang::FileID FID = SM.translateFile(*FE);
3267 if (!FID.isInvalid() && FID.getHashValue() == 0)
3268 return kFALSE;
3269 else {
3270 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3271 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3272 return kFALSE;
3273 if (!FID.isInvalid())
3274 return kTRUE;
3275 }
3276 // ...then check shared library again, but with full path now
3277 sFilename = FE->getName().str();
3279 && fileMap.count(sFilename.Data())) {
3280 return kTRUE;
3281 }
3282 }
3283 return kFALSE;
3284}
3285
3286
3287#if defined(R__MACOSX)
3288
3289////////////////////////////////////////////////////////////////////////////////
3290/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3291/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3292/// to `-lFOO` such that it can be passed to the linker.
3293/// This is a unique feature of macOS 11.
3294
3295static bool R__UpdateLibFileForLinking(TString &lib)
3296{
3297 const char *mapfile = nullptr;
3298#if __x86_64__
3299 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3300#elif __arm64__
3301 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3302#else
3303 #error unsupported architecture
3304#endif
3305 if (std::ifstream cacheMap{mapfile}) {
3306 std::string line;
3307 while (getline(cacheMap, line)) {
3308 if (line.find(lib) != std::string::npos) {
3309 lib.ReplaceAll("/usr/lib/lib","-l");
3310 lib.ReplaceAll(".dylib","");
3311 return true;
3312 }
3313 }
3314 return false;
3315 }
3316 return false;
3317}
3318#endif // R__MACOSX
3319
3320#if defined (R__LINUX) || defined (R__FBSD)
3321
3322////////////////////////////////////////////////////////////////////////////////
3323/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3324/// Collects opened libraries.
3325
3326static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3327{
3328 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3329 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3330
3331 auto newLibs = static_cast<std::vector<std::string>*>(data);
3332 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3333 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3334 if (info->dlpi_name && info->dlpi_name[0]
3335#if defined(R__FBSD)
3336 //skip the executable (with null addr)
3337 && info->dlpi_addr
3338 //has no path
3339 && strncmp(info->dlpi_name, "[vdso]", 6)
3340 //the linker does not like to be mmapped
3341 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3342 //with error message "mmap of entire address space failed: Cannot allocate memory"
3343 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3344#endif
3345 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3346 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3347 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3348 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3349 newLibs->emplace_back(info->dlpi_name);
3350 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3351 }
3352 // No matter what the doc says, return != 0 means "stop the iteration".
3353 return 0;
3354}
3355
3356#endif // R__LINUX || R__FBSD
3357
3358
3359////////////////////////////////////////////////////////////////////////////////
3360
3362{
3363#if defined(R__WIN32) || defined(__CYGWIN__)
3364 HMODULE hModules[1024];
3365 void *hProcess;
3366 unsigned long cbModules;
3367 unsigned int i;
3368 hProcess = (void *)::GetCurrentProcess();
3370 // start at 1 to skip the executable itself
3371 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3372 static const int bufsize = 260;
3373 wchar_t winname[bufsize];
3374 char posixname[bufsize];
3376#if defined(__CYGWIN__)
3378#else
3379 std::wstring wpath = winname;
3380 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3381 string path(wpath.begin(), wpath.end());
3382 strncpy(posixname, path.c_str(), bufsize);
3383#endif
3386 }
3387 }
3388#elif defined(R__MACOSX)
3389 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3390 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3391
3393 // Skip non-dylibs
3394 if (mh->filetype == MH_DYLIB) {
3395 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3397 }
3398 }
3399
3400 ++imageIndex;
3401 }
3402 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3403#elif defined(R__LINUX) || defined(R__FBSD)
3404 // fPrevLoadedDynLibInfo is unused on Linux.
3405 (void) fPrevLoadedDynLibInfo;
3406
3407 std::vector<std::string> newLibs;
3409 for (auto &&lib: newLibs)
3410 RegisterLoadedSharedLibrary(lib.c_str());
3411#else
3412 Error("TCling::UpdateListOfLoadedSharedLibraries",
3413 "Platform not supported!");
3414#endif
3415}
3416
3417namespace {
3418template <int N>
3419static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3420 return !strncmp(haystack, needle, N - 1);
3421}
3422}
3423
3424////////////////////////////////////////////////////////////////////////////////
3425/// Register a new shared library name with the interpreter; add it to
3426/// fSharedLibs.
3427
3429{
3430 // Ignore NULL filenames, aka "the process".
3431 if (!filename) return;
3432
3433 // Tell the interpreter that this library is available; all libraries can be
3434 // used to resolve symbols.
3435 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3436 if (!DLM->isLibraryLoaded(filename)) {
3437 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3438 }
3439
3440#if defined(R__MACOSX)
3441 // Check that this is not a system library that does not exist on disk.
3442 auto lenFilename = strlen(filename);
3443 auto isInMacOSSystemDir = [](const char *fn) {
3444 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3445 };
3446 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3447
3448 // These we should not link with (e.g. because they forward to .tbd):
3449 || StartsWithStrLit(filename, "/usr/lib/system/")
3450 || StartsWithStrLit(filename, "/usr/lib/libc++")
3451 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3452 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3453 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3454 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3455 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3456 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3457 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3458 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3459 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3460 || StartsWithStrLit(filename, "/usr/lib/libauto")
3461 || StartsWithStrLit(filename, "/usr/lib/libcups")
3462 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3463 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3464 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3465 || StartsWithStrLit(filename, "/usr/lib/libpam")
3466 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3467 || StartsWithStrLit(filename, "/usr/lib/libextension")
3468 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3469 || StartsWithStrLit(filename, "/usr/lib/liboah")
3470 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3471 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3472 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3473 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3474
3475 // The system lib is likely in macOS's blob.
3477
3478 // "Link against the umbrella framework 'System.framework' instead"
3479 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3480 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3481 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3482
3483 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3484 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3485 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3486 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3487 return;
3490 filename = sFileName.Data();
3491#elif defined(__CYGWIN__)
3492 // Check that this is not a system library
3493 static const int bufsize = 260;
3494 char posixwindir[bufsize];
3495 char *windir = getenv("WINDIR");
3496 if (windir)
3498 else
3499 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3500 if (strstr(filename, posixwindir) ||
3501 strstr(filename, "/usr/bin/cyg"))
3502 return;
3503#elif defined(R__WIN32)
3504 if (strstr(filename, "/Windows/"))
3505 return;
3506#elif defined (R__LINUX)
3507 if (strstr(filename, "/ld-linux")
3508 || strstr(filename, "linux-gnu/")
3509 || strstr(filename, "/libstdc++.")
3510 || strstr(filename, "/libgcc")
3511 || strstr(filename, "/libc.")
3512 || strstr(filename, "/libdl.")
3513 || strstr(filename, "/libm."))
3514 return;
3515#endif
3516 // Update string of available libraries.
3517 if (!fSharedLibs.IsNull()) {
3518 fSharedLibs.Append(" ");
3519 }
3521}
3522
3523////////////////////////////////////////////////////////////////////////////////
3524/// Load a library file in cling's memory.
3525/// if 'system' is true, the library is never unloaded.
3526/// Return 0 on success, -1 on failure.
3527
3529{
3530 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3531
3532 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3534 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3535 std::string canonLib = DLM->lookupLibrary(filename);
3536 cling::DynamicLibraryManager::LoadLibResult res
3537 = cling::DynamicLibraryManager::kLoadLibNotFound;
3538 if (!canonLib.empty()) {
3539 if (system)
3540 res = DLM->loadLibrary(filename, system, true);
3541 else {
3542 // For the non system libs, we'd like to be able to unload them.
3543 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3544 cling::Interpreter::CompilationResult compRes;
3545 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3546 if (compRes == cling::Interpreter::kSuccess)
3547 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3548 }
3549 }
3550
3551 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3553 }
3554 switch (res) {
3555 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3556 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3557 default: break;
3558 };
3559 return -1;
3560}
3561
3562////////////////////////////////////////////////////////////////////////////////
3563/// Load a macro file in cling's memory.
3564
3565void TCling::LoadMacro(const char* filename, EErrorCode* error)
3566{
3567 ProcessLine(Form(".L %s", filename), error);
3568}
3569
3570////////////////////////////////////////////////////////////////////////////////
3571/// Let cling process a command line asynch.
3572
3574{
3575 return ProcessLine(line, error);
3576}
3577
3578////////////////////////////////////////////////////////////////////////////////
3579/// Let cling process a command line synchronously, i.e we are waiting
3580/// it will be finished.
3581
3583{
3585 if (gApplication) {
3586 if (gApplication->IsCmdThread()) {
3587 return ProcessLine(line, error);
3588 }
3589 return 0;
3590 }
3591 return ProcessLine(line, error);
3592}
3593
3594////////////////////////////////////////////////////////////////////////////////
3595/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3596/// however not declarations, like "Int_t x;").
3597
3599{
3600#ifdef R__WIN32
3601 // Test on ApplicationImp not being 0 is needed because only at end of
3602 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3603 // we can not use it.
3605 while (gROOT->IsLineProcessing() && !gApplication) {
3606 Warning("Calc", "waiting for cling thread to free");
3607 gSystem->Sleep(500);
3608 }
3609 gROOT->SetLineIsProcessing();
3610 }
3611#endif // R__WIN32
3613 if (error) {
3614 *error = TInterpreter::kNoError;
3615 }
3616 cling::Value valRef;
3617 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3618 try {
3619 cr = fInterpreter->evaluate(line, valRef);
3620 }
3621 catch (cling::InterpreterException& ex)
3622 {
3623 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3624 ex.diagnose();
3625 cr = cling::Interpreter::kFailure;
3626 }
3627
3628 if (cr != cling::Interpreter::kSuccess) {
3629 // Failure in compilation.
3630 if (error) {
3631 // Note: Yes these codes are weird.
3633 }
3634 return 0L;
3635 }
3636 if (!valRef.isValid()) {
3637 // Failure at runtime.
3638 if (error) {
3639 // Note: Yes these codes are weird.
3640 *error = TInterpreter::kDangerous;
3641 }
3642 return 0L;
3643 }
3644
3645 if (valRef.isVoid()) {
3646 return 0;
3647 }
3648
3650#ifdef R__WIN32
3652 gROOT->SetLineHasBeenProcessed();
3653 }
3654#endif // R__WIN32
3655 return valRef.castAs<Longptr_t>();
3656}
3657
3658////////////////////////////////////////////////////////////////////////////////
3659/// Set a getline function to call when input is needed.
3660
3661void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3662 void (*histaddFunc)(const char* line))
3663{
3664 // If cling offers a replacement for G__pause(), it would need to
3665 // also offer a way to customize at least the history recording.
3666
3667#if defined(R__MUST_REVISIT)
3668#if R__MUST_REVISIT(6,2)
3669 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3670#endif
3671#endif
3672}
3673
3674////////////////////////////////////////////////////////////////////////////////
3675/// Helper function to increase the internal Cling count of transactions
3676/// that change the AST.
3677
3678Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3679{
3681
3682 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3683 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3684 || T.macros_begin() != T.macros_end()
3685 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3687 return true;
3688 }
3689 return false;
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Delete object from cling symbol table so it can not be used anymore.
3694/// cling objects are always on the heap.
3695
3697{
3698 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3699 // put in place the Read/Write part here. Keeping the write lock
3700 // here is 'catasptrophic' for scaling as it means that ALL calls
3701 // to RecursiveRemove will take the write lock and performance
3702 // of many threads trying to access the write lock at the same
3703 // time is relatively bad.
3705 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3706 // (but isn't at the moment).
3707 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3708 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3709 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3711 DeleteGlobal(obj);
3712 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3713 }
3714 }
3715}
3716
3717////////////////////////////////////////////////////////////////////////////////
3718/// Pressing Ctrl+C should forward here. In the case where we have had
3719/// continuation requested we must reset it.
3720
3722{
3723 fMetaProcessor->cancelContinuation();
3724 // Reset the Cling state to the state saved by the last call to
3725 // TCling::SaveContext().
3726#if defined(R__MUST_REVISIT)
3727#if R__MUST_REVISIT(6,2)
3729 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3730#endif
3731#endif
3732}
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Reset the Cling state to its initial state.
3736
3738{
3739#if defined(R__MUST_REVISIT)
3740#if R__MUST_REVISIT(6,2)
3742 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3743#endif
3744#endif
3745}
3746
3747////////////////////////////////////////////////////////////////////////////////
3748/// Reset in Cling the list of global variables to the state saved by the last
3749/// call to TCling::SaveGlobalsContext().
3750///
3751/// Note: Right now, all we do is run the global destructors.
3752
3754{
3756 // TODO:
3757 // Here we should iterate over the transactions (N-3) and revert.
3758 // N-3 because the first three internal to cling.
3759
3760 fInterpreter->runAndRemoveStaticDestructors();
3761}
3762
3763////////////////////////////////////////////////////////////////////////////////
3764/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3765/// call to TCling::SaveGlobalsContext().
3766
3768{
3769#if defined(R__MUST_REVISIT)
3770#if R__MUST_REVISIT(6,2)
3772 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3773#endif
3774#endif
3775}
3776
3777////////////////////////////////////////////////////////////////////////////////
3778/// Rewind Cling dictionary to the point where it was before executing
3779/// the current macro. This function is typically called after SEGV or
3780/// ctlr-C after doing a longjmp back to the prompt.
3781
3783{
3784#if defined(R__MUST_REVISIT)
3785#if R__MUST_REVISIT(6,2)
3787 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3788#endif
3789#endif
3790}
3791
3792////////////////////////////////////////////////////////////////////////////////
3793/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3794/// Returns 1 in case of success and 0 in case object was not in table.
3795
3797{
3798#if defined(R__MUST_REVISIT)
3799#if R__MUST_REVISIT(6,2)
3801 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3802#endif
3803#endif
3804 return 0;
3805}
3806
3807////////////////////////////////////////////////////////////////////////////////
3808/// Undeclare obj called name.
3809/// Returns 1 in case of success, 0 for failure.
3810
3812{
3813#if defined(R__MUST_REVISIT)
3814#if R__MUST_REVISIT(6,2)
3815 Warning("DeleteVariable","should do more that just reseting the value to zero");
3816#endif
3817#endif
3818
3820 llvm::StringRef srName(name);
3821 const char* unscopedName = name;
3822 llvm::StringRef::size_type posScope = srName.rfind("::");
3823 const clang::DeclContext* declCtx = nullptr;
3824 if (posScope != llvm::StringRef::npos) {
3825 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3826 const clang::Decl* scopeDecl
3827 = lh.findScope(srName.substr(0, posScope),
3828 cling::LookupHelper::WithDiagnostics);
3829 if (!scopeDecl) {
3830 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3831 name);
3832 return 0;
3833 }
3834 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3835 if (!declCtx) {
3836 Error("DeleteVariable",
3837 "Enclosing scope for variable %s is not a declaration context",
3838 name);
3839 return 0;
3840 }
3841 unscopedName += posScope + 2;
3842 }
3843 // Could trigger deserialization of decls.
3844 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3845 clang::NamedDecl* nVarDecl
3846 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3847 if (!nVarDecl) {
3848 Error("DeleteVariable", "Unknown variable %s", name);
3849 return 0;
3850 }
3851 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3852 if (!varDecl) {
3853 Error("DeleteVariable", "Entity %s is not a variable", name);
3854 return 0;
3855 }
3856
3857 clang::QualType qType = varDecl->getType();
3858 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3859 // Cannot set a reference's address to nullptr; the JIT can place it
3860 // into read-only memory (ROOT-7100).
3861 if (type->isPointerType()) {
3862 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3863 // set pointer to invalid.
3864 if (ppInt) *ppInt = nullptr;
3865 }
3866 return 1;
3867}
3868
3869////////////////////////////////////////////////////////////////////////////////
3870/// Save the current Cling state.
3871
3873{
3874#if defined(R__MUST_REVISIT)
3875#if R__MUST_REVISIT(6,2)
3877 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3878#endif
3879#endif
3880}
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Save the current Cling state of global objects.
3884
3886{
3887#if defined(R__MUST_REVISIT)
3888#if R__MUST_REVISIT(6,2)
3890 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3891#endif
3892#endif
3893}
3894
3895////////////////////////////////////////////////////////////////////////////////
3896/// No op: see TClingCallbacks (used to update the list of globals)
3897
3901
3902////////////////////////////////////////////////////////////////////////////////
3903/// No op: see TClingCallbacks (used to update the list of global functions)
3904
3908
3909////////////////////////////////////////////////////////////////////////////////
3910/// No op: see TClingCallbacks (used to update the list of types)
3911
3913{
3914}
3915
3916////////////////////////////////////////////////////////////////////////////////
3917/// Check in what order the member of a tuple are layout.
3918enum class ETupleOrdering {
3919 kAscending,
3922};
3923
3929
3935
3937{
3938 std::tuple<int,double> value;
3941
3942 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3943 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3944
3945 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3946 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3947
3948 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3949 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3950
3951 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3953 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3955 } else {
3957 }
3958}
3959
3960static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3961{
3963 std::string alternateName = "TEmulatedTuple";
3964 alternateName.append( classname + 5 );
3965
3966 std::string fullname = "ROOT::Internal::" + alternateName;
3967 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3968 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3969 return fullname;
3970
3971 {
3972 // Check if we can produce the tuple
3973 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3974 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3975 auto deleter = [](TypeInfo_t *type) {
3976 gInterpreter->TypeInfo_Delete(type);
3977 };
3978 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
3979 while (iter != theEnd) {
3980 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
3981 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
3982 if (!silent)
3983 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
3984 classname, iter->c_str());
3985 return "";
3986 }
3987 ++iter;
3988 }
3989 }
3990
3991 std::string guard_name;
3993 std::ostringstream guard;
3994 guard << "ROOT_INTERNAL_TEmulated_";
3995 guard << guard_name;
3996
3997 std::ostringstream alternateTuple;
3998 alternateTuple << "#ifndef " << guard.str() << "\n";
3999 alternateTuple << "#define " << guard.str() << "\n";
4000 alternateTuple << "namespace ROOT { namespace Internal {\n";
4001 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4002 alternateTuple << "template <> struct " << alternateName << " {\n";
4003
4004 // This could also be a compile time choice ...
4005 switch(IsTupleAscending()) {
4007 unsigned int nMember = 0;
4008 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4009 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4010 while (iter != theEnd) {
4011 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4012 ++iter;
4013 ++nMember;
4014 }
4015 break;
4016 }
4018 unsigned int nMember = tupleContent.fElements.size() - 3;
4019 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4020 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4021 while (iter != theEnd) {
4022 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4023 ++iter;
4024 --nMember;
4025 }
4026 break;
4027 }
4029 Fatal("TCling::SetClassInfo::AlternateTuple",
4030 "Layout of std::tuple on this platform is unexpected.");
4031 break;
4032 }
4033 }
4034
4035 alternateTuple << "};\n";
4036 alternateTuple << "}}\n";
4037 alternateTuple << "#endif\n";
4038 if (!gCling->Declare(alternateTuple.str().c_str()))
4039 {
4040 // Declare is not silent (yet?), so add an explicit error message
4041 // to indicate the consequence of the syntax errors.
4042 Error("Load","Could not declare %s",alternateName.c_str());
4043 return "";
4044 }
4045 alternateName = "ROOT::Internal::" + alternateName;
4046 return alternateName;
4047}
4048
4049////////////////////////////////////////////////////////////////////////////////
4050/// Set pointer to the TClingClassInfo in TClass.
4051/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4052/// already have one.
4053
4055{
4056 // We are shutting down, there is no point in reloading, it only triggers
4057 // redundant deserializations.
4058 if (fIsShuttingDown) {
4059 // Remove the decl_id from the DeclIdToTClass map
4060 if (cl->fClassInfo) {
4063 // Test again as another thread may have set fClassInfo to nullptr.
4064 if (TClinginfo) {
4066 }
4067 delete TClinginfo;
4068 cl->fClassInfo = nullptr;
4069 }
4070 return;
4071 }
4072
4074 if (cl->fClassInfo && !reload) {
4075 return;
4076 }
4077 //Remove the decl_id from the DeclIdToTClass map
4079 if (TClinginfo) {
4081 }
4082 delete TClinginfo;
4083 cl->fClassInfo = nullptr;
4084 std::string name(cl->GetName());
4085
4086 auto SetWithoutClassInfoState = [](TClass *cl)
4087 {
4088 if (cl->fState != TClass::kHasTClassInit) {
4089 if (cl->fStreamerInfo->GetEntries() != 0) {
4091 } else {
4093 }
4094 }
4095 };
4096 // Handle the special case of 'tuple' where we ignore the real implementation
4097 // details and just overlay a 'simpler'/'simplistic' version that is easy
4098 // for the I/O to understand and handle.
4099 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4100 if (!reload)
4101 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4102 if (reload || name.empty()) {
4103 // We could not generate the alternate
4105 return;
4106 }
4107 }
4108
4110 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4111 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4112 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4113 // TClingClassInfoReadOnly.
4115 if (!info->IsValid()) {
4117 delete info;
4118 return;
4119 }
4120 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4121 // In case a class contains an external enum, the enum will be seen as a
4122 // class. We must detect this special case and make the class a Zombie.
4123 // Here we assume that a class has at least one method.
4124 // We can NOT call TClass::Property from here, because this method
4125 // assumes that the TClass is well formed to do a lot of information
4126 // caching. The method SetClassInfo (i.e. here) is usually called during
4127 // the building phase of the TClass, hence it is NOT well formed yet.
4129 if (
4130 info->IsValid() &&
4131 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4132 ) {
4134 }
4135 if (!info->IsLoaded()) {
4136 if (info->Property() & (kIsNamespace)) {
4137 // Namespaces can have info but no corresponding CINT dictionary
4138 // because they are auto-created if one of their contained
4139 // classes has a dictionary.
4141 }
4142 // this happens when no dictionary is available
4143 delete info;
4144 cl->fClassInfo = nullptr;
4145 }
4146 if (zombieCandidate && !cl->GetCollectionType()) {
4147 cl->MakeZombie();
4148 }
4149 // If we reach here, the info was valid (See early returns).
4150 if (cl->fState != TClass::kHasTClassInit) {
4151 if (cl->fClassInfo) {
4153 } else {
4154// if (TClassEdit::IsSTLCont(cl->GetName()) {
4155// There will be an emulated collection proxy, is that the same?
4156// cl->fState = TClass::kEmulated;
4157// } else {
4158 if (cl->fStreamerInfo->GetEntries() != 0) {
4160 } else {
4162 }
4163// }
4164 }
4165 }
4166 if (cl->fClassInfo) {
4167 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4168 }
4169}
4170
4171////////////////////////////////////////////////////////////////////////////////
4172/// Checks if an entity with the specified name is defined in Cling.
4173/// Returns kUnknown if the entity is not defined.
4174/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4175/// Returns kKnown if the entity is defined.
4176///
4177/// By default, structs, namespaces, classes, enums and unions are looked for.
4178/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4179/// namespaces only are considered. I.e. if the name is an enum or a union,
4180/// the returned value is false.
4181///
4182/// In the case where the class is not loaded and belongs to a namespace
4183/// or is nested, looking for the full class name is outputting a lots of
4184/// (expected) error messages. Currently the only way to avoid this is to
4185/// specifically check that each level of nesting is already loaded.
4186/// In case of templates the idea is that everything between the outer
4187/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4188
4191{
4193 static const char *anonEnum = "anonymous enum ";
4194 static const int cmplen = strlen(anonEnum);
4195
4196 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4197 return kUnknown;
4198 }
4199
4200 // Do not turn on the AutoLoading if it is globally off.
4202
4203 // Avoid the double search below in case the name is a fundamental type
4204 // or typedef to a fundamental type.
4205 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4206 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4207
4209 && fundType->GetType() > 0) {
4210 // Fundamental type, no a class.
4211 return kUnknown;
4212 }
4213
4214 // Migrated from within TClass::GetClass
4215 // If we want to know if a class or a namespace with this name exists in the
4216 // interpreter and this is an enum in the type system, before or after loading
4217 // according to the autoload function argument, return kUnknown.
4219 return kUnknown;
4220
4221 const char *classname = name;
4222
4223 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4225 int fStoreAutoLoad = 0;
4226 int fStoreAutoParse = 0;
4227 bool fSuspendedAutoParse = false;
4228 public:
4230 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4231 }
4232
4233 void SuspendAutoParsing() {
4234 fSuspendedAutoParse = true;
4235 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4236 }
4237
4240 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4241 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4242 }
4243 };
4244
4246 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4247 autoLoadParseRAII.SuspendAutoParsing();
4248
4249 // First we want to check whether the decl exist, but _without_
4250 // generating any template instantiation. However, the lookup
4251 // still will create a forward declaration of the class template instance
4252 // if it exist. In this case, the return value of findScope will still
4253 // be zero but the type will be initialized.
4254 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4255 // this forward declaration.
4256 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4257 const clang::Type *type = nullptr;
4258 const clang::Decl *decl
4259 = lh.findScope(classname,
4260 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4261 : cling::LookupHelper::NoDiagnostics,
4262 &type, /* intantiateTemplate= */ false );
4263 if (!decl) {
4264 std::string buf = TClassEdit::InsertStd(classname);
4265 decl = lh.findScope(buf,
4266 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4267 : cling::LookupHelper::NoDiagnostics,
4268 &type,false);
4269 }
4270
4271 if (type) {
4272 // If decl==0 and the type is valid, then we have a forward declaration.
4273 if (!decl) {
4274 // If we have a forward declaration for a class template instantiation,
4275 // we want to ignore it if it was produced/induced by the call to
4276 // findScope, however we can not distinguish those from the
4277 // instantiation induce by 'soft' use (and thus also induce by the
4278 // same underlying code paths)
4279 // ['soft' use = use not requiring a complete definition]
4280 // So to reduce the amount of disruption to the existing code we
4281 // would just ignore those for STL collection, for which we really
4282 // need to have the compiled collection proxy (and thus the TClass
4283 // bootstrap).
4284 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4285 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4286 (type->getAsCXXRecordDecl());
4287 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4288 // Since the point of instantiation is invalid, we 'guess' that
4289 // the 'instantiation' of the forwarded type appended in
4290 // findscope.
4292 // For STL Collection we return kUnknown.
4293 return kUnknown;
4294 }
4295 }
4296 }
4298 if (!tci.IsValid()) {
4299 return kUnknown;
4300 }
4303
4304 if (tci.Property() & propertiesMask) {
4305 bool hasClassDefInline = false;
4307 // We do not need to check for ClassDefInline when this is called from
4308 // TClass::Init, we only do it for the call from TClass::GetClass.
4309 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4310 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4311
4312 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4313 int lineNumber = 0;
4314 bool success = false;
4315 std::tie(success, lineNumber) =
4318 }
4319 }
4320
4321 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4322 // , hasClassDefInline);
4323
4324 // We are now sure that the entry is not in fact an autoload entry.
4326 return kWithClassDefInline;
4327 else
4328 return kKnown;
4329 } else {
4330 // We are now sure that the entry is not in fact an autoload entry.
4331 return kUnknown;
4332 }
4333 }
4334
4335 if (decl)
4336 return kKnown;
4337 else
4338 return kUnknown;
4339
4340 // Setting up iterator part of TClingTypedefInfo is too slow.
4341 // Copy the lookup code instead:
4342 /*
4343 TClingTypedefInfo t(fInterpreter, name);
4344 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4345 delete[] classname;
4346 return kTRUE;
4347 }
4348 */
4349
4350// const clang::Decl *decl = lh.findScope(name);
4351// if (!decl) {
4352// std::string buf = TClassEdit::InsertStd(name);
4353// decl = lh.findScope(buf);
4354// }
4355
4356// return (decl);
4357}
4358
4359////////////////////////////////////////////////////////////////////////////////
4360/// Return true if there is a class template by the given name ...
4361
4363{
4364 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4365 // Interpreter transaction ahead, needs locking
4367 const clang::Decl *decl
4368 = lh.findClassTemplate(name,
4369 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4370 : cling::LookupHelper::NoDiagnostics);
4371 if (!decl) {
4372 std::string strname = "std::";
4373 strname += name;
4374 decl = lh.findClassTemplate(strname,
4375 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4376 : cling::LookupHelper::NoDiagnostics);
4377 }
4378 return nullptr != decl;
4379}
4380
4381////////////////////////////////////////////////////////////////////////////////
4382/// Create list of pointers to base class(es) for TClass cl.
4383
4385{
4387 if (cl->fBase) {
4388 return;
4389 }
4391 if (!tci) return;
4393 TList *listOfBase = new TList;
4394 while (t.Next()) {
4395 // if name cannot be obtained no use to put in list
4396 if (t.IsValid() && t.Name()) {
4398 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4399 }
4400 }
4401 // Now that is complete, publish it.
4402 cl->fBase = listOfBase;
4403}
4404
4405////////////////////////////////////////////////////////////////////////////////
4406/// Create list of pointers to enums for TClass cl.
4407
4409{
4411
4412 const Decl * D;
4413 TClass* cl = enumList.GetClass();
4414 if (cl) {
4415 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4416 }
4417 else {
4418 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4419 }
4420 // Iterate on the decl of the class and get the enums.
4421 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4422 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4423 // Collect all contexts of the namespace.
4424 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4425 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4427 declIter != declEnd; ++declIter) {
4428 // Iterate on all decls for each context.
4429 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4430 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4431 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4432 // Get name of the enum type.
4433 std::string buf;
4434 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4435 llvm::raw_string_ostream stream(buf);
4436 // Don't trigger fopen of the source file to count lines:
4437 Policy.AnonymousTagLocations = false;
4438 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4439 stream.flush();
4440 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4441 if (!buf.empty()) {
4442 const char* name = buf.c_str();
4443 // Add the enum to the list of loaded enums.
4444 enumList.Get(ED, name);
4445 }
4446 }
4447 }
4448 }
4449 }
4450}
4451
4452////////////////////////////////////////////////////////////////////////////////
4453/// Create list of pointers to function templates for TClass cl.
4454
4456{
4458
4459 const Decl * D;
4461 if (cl) {
4462 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4464 }
4465 else {
4466 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4467 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4468 }
4469 // Iterate on the decl of the class and get the enums.
4470 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4471 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4472 // Collect all contexts of the namespace.
4473 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4474 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4477 // Iterate on all decls for each context.
4478 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4479 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4480 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4481 funcTempList->Get(FTD);
4482 }
4483 }
4484 }
4485 }
4486}
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Get the scopes representing using declarations of namespace
4490
4491std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4492{
4494 return ci->GetUsingNamespaces();
4495}
4496
4497////////////////////////////////////////////////////////////////////////////////
4498/// Create list of pointers to data members for TClass cl.
4499/// This is now a nop. The creation and updating is handled in
4500/// TListOfDataMembers.
4501
4503{
4504}
4505
4506////////////////////////////////////////////////////////////////////////////////
4507/// Create list of pointers to methods 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 method for TClass cl
4517/// This is now a nop. The creation and updating is handled in
4518/// TListOfFunctions.
4519
4521{
4522}
4523
4524////////////////////////////////////////////////////////////////////////////////
4525/// Update the list of pointers to data members for TClass cl
4526/// This is now a nop. The creation and updating is handled in
4527/// TListOfDataMembers.
4528
4530{
4531}
4532
4533////////////////////////////////////////////////////////////////////////////////
4534/// Create list of pointers to method arguments for TMethod m.
4535
4537{
4539 if (m->fMethodArgs) {
4540 return;
4541 }
4542 TList *arglist = new TList;
4544 while (t.Next()) {
4545 if (t.IsValid()) {
4547 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4548 }
4549 }
4550 m->fMethodArgs = arglist;
4551}
4552
4553////////////////////////////////////////////////////////////////////////////////
4554/// Return whether we are waiting for more input either because the collected
4555/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4556
4558{
4559 return fMetaProcessor->awaitingMoreInput();
4560}
4561
4562////////////////////////////////////////////////////////////////////////////////
4563/// Generate a TClass for the given class.
4564/// Since the caller has already check the ClassInfo, let it give use the
4565/// result (via the value of emulation) rather than recalculate it.
4566
4567TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4568{
4569// For now the following line would lead to the (unwanted) instantiation
4570// of class template. This could/would need to be resurrected only if
4571// we re-introduce so sort of automatic instantiation. However this would
4572// have to include carefull look at the template parameter to avoid
4573// creating instance we can not really use (if the parameter are only forward
4574// declaration or do not have all the necessary interfaces).
4575
4576 // TClingClassInfo tci(fInterpreter, classname);
4577 // if (1 || !tci.IsValid()) {
4578
4579 Version_t version = 1;
4580 if (TClassEdit::IsSTLCont(classname)) {
4581 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4582 }
4584 TClass *cl = new TClass(classname, version, silent);
4585 if (!emulation) {
4586 // Set the class version if the class is versioned.
4587 // Note that we cannot just call CLASS::Class_Version() as we might not have
4588 // an execution engine (when invoked from rootcling).
4589
4590 // Do not call cl->GetClassVersion(), it has side effects!
4592 if (oldvers == version && cl->GetClassInfo()) {
4593 // We have a version and it might need an update.
4595 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4596 // Namespaces don't have class versions.
4597 return cl;
4598 }
4599 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4602 if (!mi.IsValid()) {
4603 if (cl->TestBit(TClass::kIsTObject)) {
4604 Error("GenerateTClass",
4605 "Cannot find %s::Class_Version()! Class version might be wrong.",
4606 cl->GetName());
4607 }
4608 return cl;
4609 }
4610 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4611 *fInterpreter);
4612 if (newvers == -1) {
4613 // Didn't manage to determine the class version from the AST.
4614 // Use runtime instead.
4615 if ((mi.Property() & kIsStatic)
4616 && !fInterpreter->isInSyntaxOnlyMode()) {
4617 // This better be a static function.
4619 callfunc.SetFunc(&mi);
4620 newvers = callfunc.ExecInt(nullptr);
4621 } else {
4622 Error("GenerateTClass",
4623 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4624 cl->GetName());
4625 }
4626 }
4627 if (newvers != oldvers) {
4628 cl->fClassVersion = newvers;
4629 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4630 }
4631 }
4632 }
4633
4634 return cl;
4635
4636// } else {
4637// return GenerateTClass(&tci,silent);
4638// }
4639}
4640
4641#if 0
4642////////////////////////////////////////////////////////////////////////////////
4643
4645{
4646 includes += info->FileName();
4647
4648 const clang::ClassTemplateSpecializationDecl *templateCl
4649 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4650 if (templateCl) {
4651 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4652 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4653 if (arg.getKind() == clang::TemplateArgument::Type) {
4654 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4655
4656 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4657 // We really need a header file.
4658 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4659 if (argdecl) {
4660 includes += ";";
4661 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4663 } else {
4664 std::string Result;
4665 llvm::raw_string_ostream OS(Result);
4666 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4667 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4668 }
4669 }
4670 }
4671 }
4672 }
4673}
4674#endif
4675
4676////////////////////////////////////////////////////////////////////////////////
4677/// Generate a TClass for the given class.
4678
4680{
4682 if (!info || !info->IsValid()) {
4683 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4684 return nullptr;
4685 }
4686 // We are in the case where we have AST nodes for this class.
4687 TClass *cl = nullptr;
4688 std::string classname;
4689 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4690 if (TClassEdit::IsSTLCont(classname)) {
4691#if 0
4692 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4693 // We need to build up the list of required headers, by
4694 // looking at each template arguments.
4697
4698 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4699 // 0 means success.
4700 cl = TClass::LoadClass(classnam.c_str(), silent);
4701 if (cl == 0) {
4702 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4703 }
4704 }
4705#endif
4706 if (cl == nullptr) {
4707 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4708 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4709 }
4710 } else {
4711 // For regular class, just create a TClass on the fly ...
4712 // Not quite useful yet, but that what CINT used to do anyway.
4713 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4714 }
4715 // Add the new TClass to the map of declid and TClass*.
4716 if (cl) {
4718 }
4719 return cl;
4720}
4721
4722////////////////////////////////////////////////////////////////////////////////
4723/// Generate the dictionary for the C++ classes listed in the first
4724/// argument (in a semi-colon separated list).
4725/// 'includes' contains a semi-colon separated list of file to
4726/// `#include` in the dictionary.
4727/// For example:
4728/// ~~~ {.cpp}
4729/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4730/// ~~~
4731/// or
4732/// ~~~ {.cpp}
4733/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4734/// ~~~
4735
4736Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4737{
4738 if (classes == nullptr || classes[0] == 0) {
4739 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4740 return 0;
4741 }
4742 // Split the input list
4743 std::vector<std::string> listClasses;
4744 for (
4745 const char* current = classes, *prev = classes;
4746 *current != 0;
4747 ++current
4748 ) {
4749 if (*current == ';') {
4750 listClasses.push_back(std::string(prev, current - prev));
4751 prev = current + 1;
4752 }
4753 else if (*(current + 1) == 0) {
4754 listClasses.push_back(std::string(prev, current + 1 - prev));
4755 prev = current + 1;
4756 }
4757 }
4758 std::vector<std::string> listIncludes;
4759 if (!includes)
4760 includes = "";
4761 for (
4762 const char* current = includes, *prev = includes;
4763 *current != 0;
4764 ++current
4765 ) {
4766 if (*current == ';') {
4767 listIncludes.push_back(std::string(prev, current - prev));
4768 prev = current + 1;
4769 }
4770 else if (*(current + 1) == 0) {
4771 listIncludes.push_back(std::string(prev, current + 1 - prev));
4772 prev = current + 1;
4773 }
4774 }
4775 // Generate the temporary dictionary file
4777 std::vector<std::string>(), std::vector<std::string>());
4778}
4779
4780////////////////////////////////////////////////////////////////////////////////
4781/// Return pointer to cling Decl of global/static variable that is located
4782/// at the address given by addr.
4783
4785{
4787 DeclId_t d;
4789
4790 // Could trigger deserialization of decls.
4791 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4792
4793 if (cl) {
4794 d = cl->GetDataMember(name);
4795 // We check if the decl of the data member has an annotation which indicates
4796 // an ioname.
4797 // In case this is true, if the name requested is not the ioname, we
4798 // return 0, as if the member did not exist. In some sense we override
4799 // the information in the TClassInfo instance, isolating the typesystem in
4800 // TClass from the one in the AST.
4801 if (const ValueDecl* decl = (const ValueDecl*) d){
4802 std::string ioName;
4804 if (hasIoName && ioName != name) return nullptr;
4805 }
4806 return d;
4807 }
4808 // We are looking up for something on the TU scope.
4809 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4810 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4811 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4812 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4813 // are only fulfilling ROOT's understanding for a Data Member.
4814 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4815 // similar as below.
4816 using namespace clang;
4817 Sema& SemaR = fInterpreter->getSema();
4818 DeclarationName DName = &SemaR.Context.Idents.get(name);
4819
4820 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4821 Sema::ForExternalRedeclaration);
4822
4823 cling::utils::Lookup::Named(&SemaR, R);
4824
4825 LookupResult::Filter F = R.makeFilter();
4826 // Filter the data-member looking decls.
4827 while (F.hasNext()) {
4828 NamedDecl *D = F.next();
4831 continue;
4832 F.erase();
4833 }
4834 F.done();
4835
4836 if (R.isSingleResult())
4837 return R.getFoundDecl();
4838 return nullptr;
4839}
4840
4841////////////////////////////////////////////////////////////////////////////////
4842/// Return pointer to cling Decl of global/static variable that is located
4843/// at the address given by addr.
4844
4846{
4848
4849 const clang::Decl* possibleEnum = nullptr;
4850 // FInd the context of the decl.
4851 if (cl) {
4853 if (cci) {
4854 const clang::DeclContext* dc = nullptr;
4855 if (const clang::Decl* D = cci->GetDecl()) {
4856 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4858 }
4859 }
4860 if (dc) {
4861 // If it is a data member enum.
4862 // Could trigger deserialization of decls.
4863 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4864 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4865 } else {
4866 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4867 }
4868 }
4869 } else {
4870 // If it is a global enum.
4871 // Could trigger deserialization of decls.
4872 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4873 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4874 }
4875 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4877 return possibleEnum;
4878 }
4879 return nullptr;
4880}
4881
4882////////////////////////////////////////////////////////////////////////////////
4883/// Return pointer to cling DeclId for a global value
4884
4885TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4886{
4887 if (!gv) return nullptr;
4888
4889 llvm::StringRef mangled_name = gv->getName();
4890
4891 int err = 0;
4892 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4893 if (err) {
4894 if (err == -2) {
4895 // It might simply be an unmangled global name.
4896 DeclId_t d;
4898 d = gcl.GetDataMember(mangled_name.str().c_str());
4899 return d;
4900 }
4901 return nullptr;
4902 }
4903
4904 std::string scopename(demangled_name_c);
4906
4907 //
4908 // Separate out the class or namespace part of the
4909 // function name.
4910 //
4911 std::string dataname;
4912
4913 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4914 scopename.erase(0, sizeof("typeinfo for ")-1);
4915 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4916 scopename.erase(0, sizeof("vtable for ")-1);
4917 } else {
4918 // See if it is a function
4919 std::string::size_type pos = scopename.rfind('(');
4920 if (pos != std::string::npos) {
4921 return nullptr;
4922 }
4923 // Separate the scope and member name
4924 pos = scopename.rfind(':');
4925 if (pos != std::string::npos) {
4926 if ((pos != 0) && (scopename[pos-1] == ':')) {
4927 dataname = scopename.substr(pos+1);
4928 scopename.erase(pos-1);
4929 }
4930 } else {
4931 scopename.clear();
4933 }
4934 }
4935 //fprintf(stderr, "name: '%s'\n", name.c_str());
4936 // Now we have the class or namespace name, so do the lookup.
4937
4938
4939 DeclId_t d;
4940 if (scopename.size()) {
4942 d = cl.GetDataMember(dataname.c_str());
4943 }
4944 else {
4946 d = gcl.GetDataMember(dataname.c_str());
4947 }
4948 return d;
4949}
4950
4951////////////////////////////////////////////////////////////////////////////////
4952/// NOT IMPLEMENTED.
4953
4955{
4956 Error("GetDataMemberWithValue()", "not implemented");
4957 return nullptr;
4958}
4959
4960////////////////////////////////////////////////////////////////////////////////
4961/// Return pointer to cling DeclId for a data member with a given name.
4962
4964{
4965 // NOT IMPLEMENTED.
4966 Error("GetDataMemberAtAddr()", "not implemented");
4967 return nullptr;
4968}
4969
4970////////////////////////////////////////////////////////////////////////////////
4971/// Return the cling mangled name for a method of a class with parameters
4972/// params (params is a string of actual arguments, not formal ones). If the
4973/// class is 0 the global function list will be searched.
4974
4976 const char* params, Bool_t objectIsConst /* = kFALSE */)
4977{
4980 if (cl) {
4983 &offset);
4984 }
4985 else {
4988 func.SetFunc(&gcl, method, params, &offset);
4989 }
4991 if (!mi) return "";
4992 TString mangled_name( mi->GetMangledName() );
4993 delete mi;
4994 return mangled_name;
4995}
4996
4997////////////////////////////////////////////////////////////////////////////////
4998/// Return the cling mangled name for a method of a class with a certain
4999/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5000/// list will be searched.
5001
5003 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5004 EFunctionMatchMode mode /* = kConversionMatch */)
5005{
5007 if (cl) {
5008 return ((TClingClassInfo*)cl->GetClassInfo())->
5009 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5010 }
5012 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5013}
5014
5015////////////////////////////////////////////////////////////////////////////////
5016/// Return pointer to cling interface function for a method of a class with
5017/// parameters params (params is a string of actual arguments, not formal
5018/// ones). If the class is 0 the global function list will be searched.
5019
5021 const char* params, Bool_t objectIsConst /* = kFALSE */)
5022{
5025 if (cl) {
5028 &offset);
5029 }
5030 else {
5033 func.SetFunc(&gcl, method, params, &offset);
5034 }
5035 return (void*) func.InterfaceMethod();
5036}
5037
5038////////////////////////////////////////////////////////////////////////////////
5039/// Return pointer to cling interface function for a method of a class with
5040/// a certain name.
5041
5043{
5045 DeclId_t f;
5047 if (cl) {
5048 f = cl->GetMethod(method).GetDeclId();
5049 }
5050 else {
5052 f = gcl.GetMethod(method).GetDeclId();
5053 }
5054 return f;
5055
5056}
5057
5058////////////////////////////////////////////////////////////////////////////////
5059/// Insert overloads of name in cl to res.
5060
5062 std::vector<DeclId_t>& res) const
5063{
5064 clang::Sema& S = fInterpreter->getSema();
5065 clang::ASTContext& Ctx = S.Context;
5066 const clang::Decl* CtxDecl
5067 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5068 Ctx.getTranslationUnitDecl();
5069 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5070 const clang::DeclContext* DeclCtx = RecDecl;
5071
5072 if (!DeclCtx)
5074 if (!DeclCtx) return;
5075
5076 clang::DeclarationName DName;
5077 // The DeclarationName is funcname, unless it's a ctor or dtor.
5078 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5079
5080 if (RecDecl) {
5081 if (RecDecl->getNameAsString() == funcname) {
5082 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5083 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5084 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5085 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5086 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5087 } else {
5088 DName = &Ctx.Idents.get(funcname);
5089 }
5090 } else {
5091 DName = &Ctx.Idents.get(funcname);
5092 }
5093
5094 // NotForRedeclaration: we want to find names in inline namespaces etc.
5095 clang::LookupResult R(S, DName, clang::SourceLocation(),
5096 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5097 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5098 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5099 if (R.empty()) return;
5100 R.resolveKind();
5101 res.reserve(res.size() + (R.end() - R.begin()));
5102 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5103 IR != ER; ++IR) {
5104 if (const clang::FunctionDecl* FD
5105 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5106 if (!FD->getDescribedFunctionTemplate()) {
5107 res.push_back(FD);
5108 }
5109 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5110 // FIXME: multi-level using
5111 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5112 res.push_back(USD);
5113 }
5114 }
5115 }
5116}
5117
5118////////////////////////////////////////////////////////////////////////////////
5119/// Return pointer to cling interface function for a method of a class with
5120/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5121/// function list will be searched.
5122
5124 const char* proto,
5125 Bool_t objectIsConst /* = kFALSE */,
5126 EFunctionMatchMode mode /* = kConversionMatch */)
5127{
5129 void* f;
5130 if (cl) {
5131 f = ((TClingClassInfo*)cl->GetClassInfo())->
5132 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5133 }
5134 else {
5136 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5137 }
5138 return f;
5139}
5140
5141////////////////////////////////////////////////////////////////////////////////
5142/// Return pointer to cling DeclId for a method of a class with
5143/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5144/// function list will be searched.
5145
5147 const char* params,
5148 Bool_t objectIsConst /* = kFALSE */)
5149{
5151 DeclId_t f;
5153 if (cl) {
5154 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5155 }
5156 else {
5158 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5159 }
5160 return f;
5161}
5162
5163////////////////////////////////////////////////////////////////////////////////
5164/// Return pointer to cling interface function for a method of a class with
5165/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5166/// function list will be searched.
5167
5169 const char* proto,
5170 Bool_t objectIsConst /* = kFALSE */,
5171 EFunctionMatchMode mode /* = kConversionMatch */)
5172{
5174 DeclId_t f;
5176 if (cl) {
5177 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5178 }
5179 else {
5181 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5182 }
5183 return f;
5184}
5185
5186////////////////////////////////////////////////////////////////////////////////
5187/// Return pointer to cling interface function for a method of a class with
5188/// a certain name.
5189
5191{
5193 DeclId_t f;
5195 if (cl) {
5196 f = cl->GetFunctionTemplate(name);
5197 }
5198 else {
5200 f = gcl.GetFunctionTemplate(name);
5201 }
5202 return f;
5203
5204}
5205
5206////////////////////////////////////////////////////////////////////////////////
5207/// The 'name' is known to the interpreter, this function returns
5208/// the internal version of this name (usually just resolving typedefs)
5209/// This is used in particular to synchronize between the name used
5210/// by rootcling and by the run-time environment (TClass)
5211/// Return 0 if the name is not known.
5212
5213void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5214{
5215 output.clear();
5216
5218
5220 if (!cl.IsValid()) {
5221 return ;
5222 }
5223 if (full) {
5225 return;
5226 }
5227 // Well well well, for backward compatibility we need to act a bit too
5228 // much like CINT.
5231
5232 return;
5233}
5234
5235////////////////////////////////////////////////////////////////////////////////
5236/// Execute a global function with arguments params.
5237///
5238/// FIXME: The cint-based version of this code does not check if the
5239/// SetFunc() call works, and does not do any real checking
5240/// for errors from the Exec() call. It did fetch the most
5241/// recent cint security error and return that in error, but
5242/// this does not really translate well to cling/clang. We
5243/// should enhance these interfaces so that we can report
5244/// compilation and runtime errors properly.
5245
5246void TCling::Execute(const char* function, const char* params, int* error)
5247{
5249 if (error) {
5250 *error = TInterpreter::kNoError;
5251 }
5253 Longptr_t offset = 0L;
5255 func.SetFunc(&cl, function, params, &offset);
5256 func.Exec(nullptr);
5257}
5258
5259////////////////////////////////////////////////////////////////////////////////
5260/// Execute a method from class cl with arguments params.
5261///
5262/// FIXME: The cint-based version of this code does not check if the
5263/// SetFunc() call works, and does not do any real checking
5264/// for errors from the Exec() call. It did fetch the most
5265/// recent cint security error and return that in error, but
5266/// this does not really translate well to cling/clang. We
5267/// should enhance these interfaces so that we can report
5268/// compilation and runtime errors properly.
5269
5270void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5271 const char* params, Bool_t objectIsConst, int* error)
5272{
5274 if (error) {
5275 *error = TInterpreter::kNoError;
5276 }
5277 // If the actual class of this object inherits 2nd (or more) from TObject,
5278 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5279 // hence gInterpreter->Execute will improperly correct the offset.
5280 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5281 Longptr_t offset = 0L;
5284 void* address = (void*)((Longptr_t)addr + offset);
5285 func.Exec(address);
5286}
5287
5288////////////////////////////////////////////////////////////////////////////////
5289
5290void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5291 const char* params, int* error)
5292{
5293 Execute(obj,cl,method,params,false,error);
5294}
5295
5296////////////////////////////////////////////////////////////////////////////////
5297/// Execute a method from class cl with the arguments in array params
5298/// (params[0] ... params[n] = array of TObjString parameters).
5299/// Convert the TObjArray array of TObjString parameters to a character
5300/// string of comma separated parameters.
5301/// The parameters of type 'char' are enclosed in double quotes and all
5302/// internal quotes are escaped.
5303
5305 TObjArray* params, int* error)
5306{
5307 if (!method) {
5308 Error("Execute", "No method was defined");
5309 return;
5310 }
5311 TList* argList = method->GetListOfMethodArgs();
5312 // Check number of actual parameters against of expected formal ones
5313
5314 Int_t nparms = argList->LastIndex() + 1;
5315 Int_t argc = params ? params->GetEntries() : 0;
5316
5317 if (argc > nparms) {
5318 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5319 return;
5320 }
5321 if (nparms != argc) {
5322 // Let's see if the 'missing' argument are all defaulted.
5323 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5324 assert(nparms > 0);
5325
5326 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5327 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5328 // There is a default value for the first missing
5329 // argument, so we are fine.
5330 } else {
5331 Int_t firstDefault = -1;
5332 for (Int_t i = 0; i < nparms; i ++) {
5333 arg = (TMethodArg *) argList->At( i );
5334 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5335 firstDefault = i;
5336 break;
5337 }
5338 }
5339 if (firstDefault >= 0) {
5340 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);
5341 } else {
5342 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5343 }
5344 return;
5345 }
5346 }
5347
5348 const char* listpar = "";
5349 TString complete(10);
5350 if (params) {
5351 // Create a character string of parameters from TObjArray
5352 TIter next(params);
5353 for (Int_t i = 0; i < argc; i ++) {
5354 TMethodArg* arg = (TMethodArg*) argList->At(i);
5356 TObjString* nxtpar = (TObjString*) next();
5357 if (i) {
5358 complete += ',';
5359 }
5360 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5361 TString chpar('\"');
5362 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5363 // At this point we have to check if string contains \\"
5364 // and apply some more sophisticated parser. Not implemented yet!
5365 complete += chpar;
5366 complete += '\"';
5367 }
5368 else {
5369 complete += nxtpar->String();
5370 }
5371 }
5372 listpar = complete.Data();
5373 }
5374
5375 // And now execute it.
5377 if (error) {
5378 *error = TInterpreter::kNoError;
5379 }
5380 // If the actual class of this object inherits 2nd (or more) from TObject,
5381 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5382 // hence gInterpreter->Execute will improperly correct the offset.
5383 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5386 func.Init(*minfo);
5387 func.SetArgs(listpar);
5388 // Now calculate the 'this' pointer offset for the method
5389 // when starting from the class described by cl.
5390 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5391 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5392 void* address = (void*)((Longptr_t)addr + offset);
5393 func.Exec(address);
5394}
5395
5396////////////////////////////////////////////////////////////////////////////////
5397
5399 const void* args[] /*=0*/,
5400 int nargs /*=0*/,
5401 void* ret/*= 0*/) const
5402{
5403 if (!method) {
5404 Error("ExecuteWithArgsAndReturn", "No method was defined");
5405 return;
5406 }
5407
5409 TClingCallFunc func(*minfo);
5410 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5411}
5412
5413////////////////////////////////////////////////////////////////////////////////
5414/// Execute a cling macro.
5415
5417{
5419 fCurExecutingMacros.push_back(filename);
5421 fCurExecutingMacros.pop_back();
5422 return result;
5423}
5424
5425////////////////////////////////////////////////////////////////////////////////
5426/// Return the file name of the current un-included interpreted file.
5427/// See the documentation for GetCurrentMacroName().
5428
5430{
5431 Warning("GetTopLevelMacroName", "Must change return type!");
5432 return fCurExecutingMacros.back();
5433}
5434
5435////////////////////////////////////////////////////////////////////////////////
5436/// Return the file name of the currently interpreted file,
5437/// included or not. Example to illustrate the difference between
5438/// GetCurrentMacroName() and GetTopLevelMacroName():
5439/// ~~~ {.cpp}
5440/// void inclfile() {
5441/// std::cout << "In inclfile.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/// }
5447/// ~~~
5448/// ~~~ {.cpp}
5449/// void mymacro() {
5450/// std::cout << "In mymacro.C" << std::endl;
5451/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5452/// TCling::GetCurrentMacroName() << std::endl;
5453/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5454/// TCling::GetTopLevelMacroName() << std::endl;
5455/// std::cout << " Now calling inclfile..." << std::endl;
5456/// gInterpreter->ProcessLine(".x inclfile.C");;
5457/// }
5458/// ~~~
5459/// Running mymacro.C will print:
5460///
5461/// ~~~ {.cpp}
5462/// root [0] .x mymacro.C
5463/// ~~~
5464/// In mymacro.C
5465/// ~~~ {.cpp}
5466/// TCling::GetCurrentMacroName() returns ./mymacro.C
5467/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5468/// ~~~
5469/// Now calling inclfile...
5470/// In inclfile.h
5471/// ~~~ {.cpp}
5472/// TCling::GetCurrentMacroName() returns inclfile.C
5473/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5474/// ~~~
5475
5477{
5478#if defined(R__MUST_REVISIT)
5479#if R__MUST_REVISIT(6,0)
5480 Warning("GetCurrentMacroName", "Must change return type!");
5481#endif
5482#endif
5483 return fCurExecutingMacros.back();
5484}
5485
5486////////////////////////////////////////////////////////////////////////////////
5487/// Return the absolute type of typeDesc.
5488/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5489/// You need to use the result immediately before it is being overwritten.
5490
5491const char* TCling::TypeName(const char* typeDesc)
5492{
5493 TTHREAD_TLS_DECL(std::string,t);
5494
5495 if (!strstr(typeDesc, "(*)(")) {
5496 const char *s = strchr(typeDesc, ' ');
5497 const char *template_start = strchr(typeDesc, '<');
5498 if (!strcmp(typeDesc, "long long")) {
5499 t = typeDesc;
5500 }
5501 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5502 t = typeDesc;
5503 }
5504 // s is the position of the second 'word' (if any)
5505 // except in the case of templates where there will be a space
5506 // just before any closing '>': eg.
5507 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5508 else if (s && (template_start == nullptr || (s < template_start))) {
5509 t = s + 1;
5510 }
5511 else {
5512 t = typeDesc;
5513 }
5514 }
5515 else {
5516 t = typeDesc;
5517 }
5518 auto l = t.length();
5519 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5520 --l;
5521 t.resize(l);
5522 return t.c_str(); // NOLINT
5523}
5524
5525static bool requiresRootMap(const char* rootmapfile)
5526{
5528
5529 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5530 libName.consume_back(".rootmap");
5531
5532 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5533}
5534
5535////////////////////////////////////////////////////////////////////////////////
5536/// Read and parse a rootmapfile in its new format, and return 0 in case of
5537/// success, -1 if the file has already been read, and -3 in case its format
5538/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5539/// error.
5540
5542{
5543 if (!(rootmapfile && *rootmapfile))
5544 return 0;
5545
5547 return 0; // success
5548
5549 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5550 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5551
5553#ifdef _MSC_VER
5554 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5555#endif
5556 // Add content of a specific rootmap file
5558 return -1;
5559
5560 // Line 1 is `{ decls }`
5561 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5562
5563 std::ifstream file(rootmapfileNoBackslash);
5564 std::string line;
5565 line.reserve(200);
5566 std::string lib_name;
5567 line.reserve(100);
5568 bool newFormat = false;
5569 while (getline(file, line, '\n')) {
5570 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5571 file.close();
5572 return -3; // old format
5573 }
5574 newFormat = true;
5575
5576 if (line.compare(0, 9, "{ decls }") == 0) {
5577 // forward declarations
5578
5579 while (getline(file, line, '\n')) {
5580 if (line[0] == '[')
5581 break;
5582 if (!uniqueString) {
5583 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5584 rootmapfileNoBackslash.c_str());
5585 return -4;
5586 }
5587 if (!lineDirective.empty())
5588 uniqueString->Append(lineDirective);
5589 uniqueString->Append(line + '\n');
5590 }
5591 }
5592 const char firstChar = line[0];
5593 if (firstChar == '[') {
5594 // new section (library)
5595 auto brpos = line.find(']');
5596 if (brpos == string::npos)
5597 continue;
5598 lib_name = line.substr(1, brpos - 1);
5599 // Remove spaces at the beginning and at the end of the library name
5600 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5601 lib_name.erase(0, lib_name.find_first_not_of(' '));
5602 if (gDebug > 3) {
5603 TString lib_nameTstr(lib_name.c_str());
5604 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5605 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5606 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5607 if (wlib) {
5608 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5609 } else {
5610 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5611 }
5612 delete[] wlib;
5613 delete tokens;
5614 }
5615 } else {
5616 auto keyLenIt = keyLenMap.find(firstChar);
5617 if (keyLenIt == keyLenMap.end())
5618 continue;
5619 unsigned int keyLen = keyLenIt->second;
5620 // Do not make a copy, just start after the key
5621 const char *keyname = line.c_str() + keyLen;
5622 if (gDebug > 6)
5623 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5625 if (isThere) {
5626 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5627 if (firstChar == 'n') {
5628 if (gDebug > 3)
5629 Info("ReadRootmapFile",
5630 "While processing %s, namespace %s was found to be associated to %s although it is already "
5631 "associated to %s",
5632 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5633 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5634 lib_name += " ";
5635 lib_name += isThere->GetValue();
5636 fMapfile->SetValue(keyname, lib_name.c_str());
5637 } else if (!TClassEdit::IsSTLCont(keyname)) {
5638 Warning("ReadRootmapFile",
5639 "While processing %s, %s %s was found to be associated to %s although it is already "
5640 "associated to %s",
5641 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5642 isThere->GetValue());
5643 }
5644 } else { // the same key for the same lib
5645 if (gDebug > 3)
5646 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5647 rootmapfile, keyname, lib_name.c_str());
5648 }
5649 } else {
5650 fMapfile->SetValue(keyname, lib_name.c_str());
5651 }
5652 }
5653 }
5654 file.close();
5655 return 0;
5656}
5657
5658////////////////////////////////////////////////////////////////////////////////
5659/// Create a resource table and read the (possibly) three resource files,
5660/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5661/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5662/// can read additional user defined resource files by creating additional TEnv
5663/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5664/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5665/// case the home directory resides on an automounted remote file system
5666/// and one wants to avoid the file system from being mounted.
5667
5669{
5670 assert(requiresRootMap(name) && "We have a module!");
5671
5672 if (!requiresRootMap(name))
5673 return;
5674
5676
5678
5679 TString sname = "system";
5680 sname += name;
5682
5684 if (ret == -3) // old format
5686 delete [] s;
5687 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5689 ret = ReadRootmapFile(s);
5690 if (ret == -3) // old format
5692 delete [] s;
5695 if (ret == -3) // old format
5697 }
5698 } else {
5700 if (ret == -3) // old format
5702 }
5704}
5705
5706
5707namespace {
5708 using namespace clang;
5709
5710 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5711 // This class is to be considered an helper for AutoLoading.
5712 // It is a recursive visitor is used to inspect namespaces and specializations
5713 // coming from forward declarations in rootmaps and to set the external visible
5714 // storage flag for them.
5715 public:
5716 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5717 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5718 // We want to enable the external lookup for this namespace
5719 // because it may shadow the lookup of other names contained
5720 // in that namespace
5721
5722 nsDecl->setHasExternalVisibleStorage();
5723 fNSSet.insert(nsDecl);
5724 return true;
5725 }
5727 // We want to enable the external lookup for this specialization
5728 // because we can provide a definition for it!
5729 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5730 //SpecSet.insert(specDecl);
5731 specDecl->setHasExternalLexicalStorage();
5732
5733 // No need to recurse. On the contrary, recursing is actively harmful:
5734 // NOTE: must not recurse to prevent this visitor from triggering loading from
5735 // the external AST source (i.e. autoloading). This would be triggered right here,
5736 // before autoloading is even set up, as rootmap file parsing happens before that.
5737 // Even if autoloading is off and has no effect, triggering loading from external
5738 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5739 // from subsequent autoloads!
5740 return false;
5741 }
5742 private:
5743 std::unordered_set<const NamespaceDecl*>& fNSSet;
5744 };
5745}
5746
5747////////////////////////////////////////////////////////////////////////////////
5748/// Load map between class and library. If rootmapfile is specified a
5749/// specific rootmap file can be added (typically used by ACLiC).
5750/// In case of error -1 is returned, 0 otherwise.
5751/// The interpreter uses this information to automatically load the shared
5752/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5753
5755{
5757 return 0;
5758
5760
5761 // open the [system].rootmap files
5762 if (!fMapfile) {
5763 fMapfile = new TEnv();
5767 InitRootmapFile(".rootmap");
5768 }
5769
5770 // Prepare a list of all forward declarations for cling
5771 // For some experiments it is easily as big as 500k characters. To be on the
5772 // safe side, we go for 1M.
5773 TUniqueString uniqueString(1048576);
5774
5775 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5776 // A rootmap file must end with the string ".rootmap".
5778 if (ldpath != fRootmapLoadPath) {
5780#ifdef WIN32
5781 TObjArray* paths = ldpath.Tokenize(";");
5782#else
5783 TObjArray* paths = ldpath.Tokenize(":");
5784#endif
5785 TString d;
5786 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5787 d = ((TObjString *)paths->At(i))->GetString();
5788 // check if directory already scanned
5789 Int_t skip = 0;
5790 for (Int_t j = 0; j < i; j++) {
5791 TString pd = ((TObjString *)paths->At(j))->GetString();
5792 if (pd == d) {
5793 skip++;
5794 break;
5795 }
5796 }
5797 if (!skip) {
5798 void* dirp = gSystem->OpenDirectory(d);
5799 if (dirp) {
5800 if (gDebug > 3) {
5801 Info("LoadLibraryMap", "%s", d.Data());
5802 }
5803 const char* f1;
5804 while ((f1 = gSystem->GetDirEntry(dirp))) {
5805 TString f = f1;
5806 if (f.EndsWith(".rootmap")) {
5807 TString p;
5808 p = d + "/" + f;
5810 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5811 if (gDebug > 4) {
5812 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5813 }
5815
5816 if (ret == 0)
5817 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5818 if (ret == -3) {
5819 // old format
5821 fRootmapFiles->Add(new TNamed(f, p));
5822 }
5823 }
5824 // else {
5825 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5826 // fRootmapFiles->FindObject(f)->ls();
5827 // }
5828 }
5829 }
5830 if (f.BeginsWith("rootmap")) {
5831 TString p;
5832 p = d + "/" + f;
5833 FileStat_t stat;
5834 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5835 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5836 }
5837 }
5838 }
5839 }
5841 }
5842 }
5843 delete paths;
5844 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5845 return -1;
5846 }
5847 }
5848 if (rootmapfile && *rootmapfile) {
5850 if (res == 0) {
5851 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5852 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5854 }
5855 else if (res == -3) {
5856 // old format
5861 }
5862 }
5863 TEnvRec* rec;
5864 TIter next(fMapfile->GetTable());
5865 while ((rec = (TEnvRec*) next())) {
5866 TString cls = rec->GetName();
5867 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5868 // get the first lib from the list of lib and dependent libs
5869 TString libs = rec->GetValue();
5870 if (libs == "") {
5871 continue;
5872 }
5873 TString delim(" ");
5874 TObjArray* tokens = libs.Tokenize(delim);
5875 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5876 // convert "@@" to "::", we used "@@" because TEnv
5877 // considers "::" a terminator
5878 cls.Remove(0, 8);
5879 cls.ReplaceAll("@@", "::");
5880 // convert "-" to " ", since class names may have
5881 // blanks and TEnv considers a blank a terminator
5882 cls.ReplaceAll("-", " ");
5883 if (gDebug > 6) {
5884 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5885 if (wlib) {
5886 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5887 }
5888 else {
5889 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5890 }
5891 delete[] wlib;
5892 }
5893 delete tokens;
5894 }
5895 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5896 cls.Remove(0, 8);
5897 // convert "-" to " ", since class names may have
5898 // blanks and TEnv considers a blank a terminator
5899 cls.ReplaceAll("-", " ");
5900 fInterpreter->declare(cls.Data());
5901 }
5902 }
5903
5904 // Process the forward declarations collected
5905 cling::Transaction* T = nullptr;
5906 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5907 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5908
5909 if (compRes!=cling::Interpreter::kSuccess){
5910 Warning("LoadLibraryMap",
5911 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5912 }
5913
5914 if (T) {
5915 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5916 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5917 if (declIt->m_DGR.isSingleDecl()) {
5918 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5919 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5920 evsAdder.TraverseDecl(D);
5921 }
5922 }
5923 }
5924 }
5925 }
5926
5927 // clear duplicates
5928
5929 return 0;
5930}
5931
5932////////////////////////////////////////////////////////////////////////////////
5933/// Scan again along the dynamic path for library maps. Entries for the loaded
5934/// shared libraries are unloaded first. This can be useful after reseting
5935/// the dynamic path through TSystem::SetDynamicPath()
5936/// In case of error -1 is returned, 0 otherwise.
5937
5944
5945////////////////////////////////////////////////////////////////////////////////
5946/// Reload the library map entries coming from all the loaded shared libraries,
5947/// after first unloading the current ones.
5948/// In case of error -1 is returned, 0 otherwise.
5949
5951{
5953 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5954 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5955 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5956 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5959 if (ret < 0) {
5960 continue;
5961 }
5963 if (sharedLibBaseStr.EndsWith(".dll")) {
5964 rootMapBaseStr.ReplaceAll(".dll", "");
5965 }
5966 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5967 rootMapBaseStr.ReplaceAll(".DLL", "");
5968 }
5969 else if (sharedLibBaseStr.EndsWith(".so")) {
5970 rootMapBaseStr.ReplaceAll(".so", "");
5971 }
5972 else if (sharedLibBaseStr.EndsWith(".sl")) {
5973 rootMapBaseStr.ReplaceAll(".sl", "");
5974 }
5975 else if (sharedLibBaseStr.EndsWith(".dl")) {
5976 rootMapBaseStr.ReplaceAll(".dl", "");
5977 }
5978 else if (sharedLibBaseStr.EndsWith(".a")) {
5979 rootMapBaseStr.ReplaceAll(".a", "");
5980 }
5981 else {
5982 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5983 delete sharedLibL;
5984 return -1;
5985 }
5986 rootMapBaseStr += ".rootmap";
5988 if (!rootMap) {
5989 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5990 delete[] rootMap;
5991 delete sharedLibL;
5992 return -1;
5993 }
5994 const Int_t status = LoadLibraryMap(rootMap);
5995 if (status < 0) {
5996 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5997 delete[] rootMap;
5998 delete sharedLibL;
5999 return -1;
6000 }
6001 delete[] rootMap;
6002 }
6003 delete sharedLibL;
6004 return 0;
6005}
6006
6007////////////////////////////////////////////////////////////////////////////////
6008/// Unload the library map entries coming from all the loaded shared libraries.
6009/// Returns 0 if succesful
6010
6012{
6014 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6015 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6016 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6019 }
6020 delete sharedLibL;
6021 return 0;
6022}
6023
6024////////////////////////////////////////////////////////////////////////////////
6025/// Unload library map entries coming from the specified library.
6026/// Returns -1 in case no entries for the specified library were found,
6027/// 0 otherwise.
6028
6030{
6031 if (!fMapfile || !library || !*library) {
6032 return 0;
6033 }
6035 Ssiz_t idx = libname.Last('.');
6036 if (idx != kNPOS) {
6037 libname.Remove(idx);
6038 }
6039 size_t len = libname.Length();
6040 TEnvRec *rec;
6041 TIter next(fMapfile->GetTable());
6043 Int_t ret = 0;
6044 while ((rec = (TEnvRec *) next())) {
6045 TString cls = rec->GetName();
6046 if (cls.Length() > 2) {
6047 // get the first lib from the list of lib and dependent libs
6048 TString libs = rec->GetValue();
6049 if (libs == "") {
6050 continue;
6051 }
6052 TString delim(" ");
6053 TObjArray* tokens = libs.Tokenize(delim);
6054 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6055 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6056 // convert "@@" to "::", we used "@@" because TEnv
6057 // considers "::" a terminator
6058 cls.Remove(0, 8);
6059 cls.ReplaceAll("@@", "::");
6060 // convert "-" to " ", since class names may have
6061 // blanks and TEnv considers a blank a terminator
6062 cls.ReplaceAll("-", " ");
6063 }
6064 if (!strncmp(lib, libname.Data(), len)) {
6065 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6066 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6067 ret = -1;
6068 }
6069 }
6070 delete tokens;
6071 }
6072 }
6073 if (ret >= 0) {
6075 if (!library_rootmap.EndsWith(".rootmap"))
6076 library_rootmap.Append(".rootmap");
6077 TNamed* mfile = nullptr;
6080 delete mfile;
6081 }
6083 }
6084 return ret;
6085}
6086
6087////////////////////////////////////////////////////////////////////////////////
6088/// Register the AutoLoading information for a class.
6089/// libs is a space separated list of libraries.
6090
6091Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6092{
6093 if (!cls || !*cls)
6094 return 0;
6095
6096 TString key = TString("Library.") + cls;
6097 // convert "::" to "@@", we used "@@" because TEnv
6098 // considers "::" a terminator
6099 key.ReplaceAll("::", "@@");
6100 // convert "-" to " ", since class names may have
6101 // blanks and TEnv considers a blank a terminator
6102 key.ReplaceAll(" ", "-");
6103
6105 if (!fMapfile) {
6106 fMapfile = new TEnv();
6108
6111
6112 InitRootmapFile(".rootmap");
6113 }
6114 //fMapfile->SetValue(key, libs);
6116 return 1;
6117}
6118
6119////////////////////////////////////////////////////////////////////////////////
6120/// Demangle the name (from the typeinfo) and then request the class
6121/// via the usual name based interface (TClass::GetClass).
6122
6123TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6124{
6125 int err = 0;
6127 if (err) return nullptr;
6130 return theClass;
6131}
6132
6133////////////////////////////////////////////////////////////////////////////////
6134/// Load library containing the specified class. Returns 0 in case of error
6135/// and 1 in case if success.
6136
6137Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6138{
6139 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6140
6141 int err = 0;
6143 if (err) {
6144 return 0;
6145 }
6146
6147 std::string demangled_name(demangled_name_c);
6149
6150 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6151 // shortened name.
6154
6155 // No need to worry about typedef, they aren't any ... but there are
6156 // inlined namespaces ...
6157
6159 if (result == 0) {
6162 }
6163
6164 return result;
6165}
6166
6167////////////////////////////////////////////////////////////////////////////////
6168// Get the list of 'published'/'known' library for the class and load them.
6170{
6171 Int_t status = 0;
6172
6173 // lookup class to find list of dependent libraries
6175 if (!deplibs.IsNull()) {
6176 TString delim(" ");
6177 TObjArray* tokens = deplibs.Tokenize(delim);
6178 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6179 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6180 if (gROOT->LoadClass(cls, deplib) == 0) {
6181 if (gDebug > 0) {
6182 gCling->Info("TCling::AutoLoad",
6183 "loaded dependent library %s for %s", deplib, cls);
6184 }
6185 }
6186 else {
6187 gCling->Error("TCling::AutoLoad",
6188 "failure loading dependent library %s for %s",
6189 deplib, cls);
6190 }
6191 }
6192 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6193 if (lib && lib[0]) {
6194 if (gROOT->LoadClass(cls, lib) == 0) {
6195 if (gDebug > 0) {
6196 gCling->Info("TCling::AutoLoad",
6197 "loaded library %s for %s", lib, cls);
6198 }
6199 status = 1;
6200 }
6201 else {
6202 gCling->Error("TCling::AutoLoad",
6203 "failure loading library %s for %s", lib, cls);
6204 }
6205 }
6206 delete tokens;
6207 }
6208
6209 return status;
6210}
6211
6212////////////////////////////////////////////////////////////////////////////////
6213// Iterate through the data member of the class (either through the TProtoClass
6214// or through Cling) and trigger, recursively, the loading the necessary libraries.
6215// \note `cls` is expected to be already normalized!
6216// \returns 1 on success.
6217Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6218 bool nameIsNormalized)
6219{
6220 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6221 // has previously (within the same call to `AutoLoad()`) tried to load this class
6222 // and we are done, whether success or not, as it won't work better now than before,
6223 // because there is no additional information now compared to before.
6224 if (!visited.insert(std::string(cls)).second)
6225 return 1;
6226
6227 if (ShallowAutoLoadImpl(cls) == 0) {
6228 // If ShallowAutoLoadImpl() has an error, we have an error.
6229 return 0;
6230 }
6231
6232 // Now look through the TProtoClass to load the required library/dictionary
6234 for (auto element : proto->GetData()) {
6235 if (element->IsBasic())
6236 continue;
6237 const char *subtypename = element->GetTypeName();
6239 // Failure to load a dictionary is not (quite) a failure load
6240 // the top-level library. If we return false here, then
6241 // we would end up in a situation where the library and thus
6242 // the dictionary is loaded for "cls" but the TClass is
6243 // not created and/or marked as unavailable (in case where
6244 // AutoLoad is called from TClass::GetClass).
6245 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6246 }
6247 }
6248 return 1;
6249 }
6250
6251 // We found no TProtoClass for cls.
6252 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6253 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6254 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6255 {
6257 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6258 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6259 continue;
6260 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6262 // Failure to load a dictionary is not (quite) a failure load
6263 // the top-level library. See detailed comment in the TProtoClass
6264 // branch (above).
6265 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6266 }
6267 }
6268 gInterpreter->DataMemberInfo_Delete(memberinfo);
6269 }
6270 gInterpreter->ClassInfo_Delete(classinfo);
6271 return 1;
6272}
6273
6274////////////////////////////////////////////////////////////////////////////////
6275/// Load library containing the specified class. Returns 0 in case of error
6276/// and 1 in case if success.
6277
6279{
6280 // Prevent update to IsClassAutoloading between our check and our actions.
6282
6283 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6284 // rootcling (in *_rdict.pcm file generation) it is a no op.
6285 // FIXME: We should avoid calling autoload when we know we are not supposed
6286 // to and transform this check into an assert.
6288 // Never load any library from rootcling/genreflex.
6289 if (gDebug > 2) {
6290 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6291 }
6292 return 0;
6293 }
6294
6295 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6296
6298
6300 // The library is already loaded as the class's dictionary is known.
6301 // Return success.
6302 // Note: the name (cls) is expected to be normalized as it comes either
6303 // from a callbacks (that can/should calculate the normalized name from the
6304 // decl) or from TClass::GetClass (which does also calculate the normalized
6305 // name).
6306 return 1;
6307 }
6308
6309 if (gDebug > 2) {
6310 Info("TCling::AutoLoad",
6311 "Trying to autoload for %s", cls);
6312 }
6313
6314 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6315 if (gDebug > 2) {
6316 Info("TCling::AutoLoad",
6317 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6318 }
6319 return 0;
6320 }
6321 // Prevent the recursion when the library dictionary are loaded.
6323 // Try using externally provided callback first.
6324 if (fAutoLoadCallBack) {
6326 if (success)
6327 return success;
6328 }
6329
6330 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6331 // (when module are enabled) which might end up calling AutoParsing but
6332 // that should only be for the cases where the library has no generated pcm
6333 // and in that case a rootmap should be available.
6334 // This avoids a very costly operation (for generally no gain) but reduce the
6335 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6336 // file).
6338 std::unordered_set<std::string> visited;
6339 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6340}
6341
6342////////////////////////////////////////////////////////////////////////////////
6343/// Parse the payload or header.
6344
6345static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6346 Bool_t header,
6347 cling::Interpreter *interpreter)
6348{
6349 std::string code = gNonInterpreterClassDef ;
6350 if (!header) {
6351 // This is the complete header file content and not the
6352 // name of a header.
6353 code += what;
6354
6355 } else {
6356 code += ("#include \"");
6357 code += what;
6358 code += "\"\n";
6359 }
6360 code += ("#ifdef __ROOTCLING__\n"
6361 "#undef __ROOTCLING__\n"
6363 "#endif");
6364
6365 cling::Interpreter::CompilationResult cr;
6366 {
6367 // scope within which diagnostics are de-activated
6368 // For now we disable diagnostics because we saw them already at
6369 // dictionary generation time. That won't be an issue with the PCMs.
6370
6371 Sema &SemaR = interpreter->getSema();
6373 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6374
6375 #if defined(R__MUST_REVISIT)
6376 #if R__MUST_REVISIT(6,2)
6377 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6378 #endif
6379 #endif
6380
6381 cr = interpreter->parseForModule(code);
6382 }
6383 return cr;
6384}
6385
6386////////////////////////////////////////////////////////////////////////////////
6387/// Helper routine for TCling::AutoParse implementing the actual call to the
6388/// parser and looping over template parameters (if
6389/// any) and when they don't have a registered header to autoparse,
6390/// recurse over their template parameters.
6391///
6392/// Returns the number of header parsed.
6393
6395{
6396 // We assume the lock has already been taken.
6397 // R__LOCKGUARD(gInterpreterMutex);
6398
6400 unsigned long offset = 0;
6401 if (strncmp(cls, "const ", 6) == 0) {
6402 offset = 6;
6403 }
6404
6405 // Loop on the possible autoparse keys
6406 bool skipFirstEntry = false;
6407 std::vector<std::string> autoparseKeys;
6408 if (strchr(cls, '<')) {
6409 int nestedLoc = 0;
6411 // Check if we can skip the name of the template in the autoparses
6412 // Take all the scopes one by one. If all of them are in the AST, we do not
6413 // need to autoparse for that particular template.
6414 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6415 // autoparseKeys[0] is empty when the input is not a template instance.
6416 // The case strchr(cls, '<') != 0 but still not a template instance can
6417 // happens 'just' for string (GetSplit replaces the template by the short name
6418 // and then use that for thew splitting)
6420 auto tokens = templateName.Tokenize("::");
6421 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6422 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6424 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6425 auto nTokens = tokens->GetEntriesFast();
6426 for (Int_t tk = 0; tk < nTokens; ++tk) {
6427 auto scopeObj = tokens->UncheckedAt(tk);
6428 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6429 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6430 // Check if we have multiple nodes in the AST with this name
6431 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6432 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6433 if (!previousScopeAsContext) break; // this is not a context
6434 }
6435 delete tokens;
6436 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6437 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6438 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6439 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6440 skipFirstEntry = templatedDecl->hasDefinition();
6441 }
6442 }
6443 }
6444
6445 }
6446 }
6447 if (topLevel) autoparseKeys.emplace_back(cls);
6448
6449 for (const auto & apKeyStr : autoparseKeys) {
6450 if (skipFirstEntry) {
6451 skipFirstEntry=false;
6452 continue;
6453 }
6454 if (apKeyStr.empty()) continue;
6455 const char *apKey = apKeyStr.c_str();
6457 // If the class was not looked up
6458 if (gDebug > 1) {
6459 Info("TCling::AutoParse",
6460 "Starting autoparse for %s\n", apKey);
6461 }
6462 if (fLookedUpClasses.insert(normNameHash).second) {
6463 auto const &iter = fClassesHeadersMap.find(normNameHash);
6464 if (iter != fClassesHeadersMap.end()) {
6465 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6467 auto const &hNamesPtrs = iter->second;
6468 if (gDebug > 1) {
6469 Info("TCling::AutoParse",
6470 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6471 }
6472 for (auto & hName : hNamesPtrs) {
6473 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6474 if (0 != fPayloads.count(normNameHash)) {
6475 float initRSSval=0.f, initVSIZEval=0.f;
6476 (void) initRSSval; // Avoid unused var warning
6477 (void) initVSIZEval;
6478 if (gDebug > 0) {
6479 Info("AutoParse",
6480 "Parsing full payload for %s", apKey);
6483 initRSSval = 1e-3*info.fMemResident;
6484 initVSIZEval = 1e-3*info.fMemVirtual;
6485 }
6487 if (cRes != cling::Interpreter::kSuccess) {
6488 if (hName[0] == '\n')
6489 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6490 } else {
6493 if (gDebug > 0){
6496 float endRSSval = 1e-3*info.fMemResident;
6497 float endVSIZEval = 1e-3*info.fMemVirtual;
6498 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6499 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6500 }
6501 }
6502 } else if (!IsLoaded(hName)) {
6503 if (gDebug > 0) {
6504 Info("AutoParse",
6505 "Parsing single header %s", hName);
6506 }
6508 if (cRes != cling::Interpreter::kSuccess) {
6509 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6510 } else {
6512 }
6513 }
6514 }
6515 }
6516 else {
6517 // There is no header registered for this class, if this a
6518 // template, it will be instantiated if/when it is requested
6519 // and if we do no load/parse its components we might end up
6520 // not using an eventual specialization.
6521 if (strchr(apKey, '<')) {
6523 }
6524 }
6525 }
6526 }
6527
6528 return nHheadersParsed;
6529
6530}
6531
6532////////////////////////////////////////////////////////////////////////////////
6533/// Parse the headers relative to the class
6534/// Returns 1 in case of success, 0 in case of failure
6535
6537{
6538 if (llvm::StringRef(cls).contains("(lambda)"))
6539 return 0;
6540
6543 return AutoLoad(cls);
6544 } else {
6545 return 0;
6546 }
6547 }
6548
6550
6551 if (gDebug > 1) {
6552 Info("TCling::AutoParse",
6553 "Trying to autoparse for %s", cls);
6554 }
6555
6556 // The catalogue of headers is in the dictionary
6558 && !gClassTable->GetDictNorm(cls)) {
6559 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6561 fInterpreter->getSema());
6562 AutoLoad(cls, true /*knowDictNotLoaded*/);
6563 }
6564
6565 // Prevent the recursion when the library dictionary are loaded.
6567
6568 // No recursive header parsing on demand; we require headers to be standalone.
6570
6571 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6572
6574
6575 return nHheadersParsed > 0 ? 1 : 0;
6576}
6577
6578// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6579// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6580// false if not.
6581bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6582{
6584 if (errMsg.contains("undefined symbol: ")) {
6585 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6586 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6587 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6588 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6589 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6590 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6591 return true;
6592 } else {
6593 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6595 return true;
6596 }
6597
6598 return false;
6599}
6600
6601////////////////////////////////////////////////////////////////////////////////
6602/// Autoload a library based on a missing symbol.
6603
6606
6607 // We have already loaded the library.
6608 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6609 return Addr;
6610
6611 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6613
6614 auto LibLoader = [](const std::string& LibName) -> bool {
6615 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6616 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6617 "Failed to load library %s", LibName.c_str());
6618 return false;
6619 }
6620 return true; //success.
6621 };
6622
6623 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6624 /*searchSystem=*/ true);
6625
6626 assert(!llvm::StringRef(libName).startswith("libNew") &&
6627 "We must not resolve symbols from libNew!");
6628
6629 if (libName.empty())
6630 return nullptr;
6631
6632 if (!LibLoader(libName))
6633 return nullptr;
6634
6635 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6636}
6637
6638////////////////////////////////////////////////////////////////////////////////
6639
6641{
6642 return fNSFromRootmaps.count(nsDecl) != 0;
6643}
6644
6645////////////////////////////////////////////////////////////////////////////////
6646/// Internal function. Actually do the update of the ClassInfo when seeing
6647// new TagDecl or NamespaceDecl.
6648void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6649{
6650
6652 if (cci) {
6653 // If we only had a forward declaration then update the
6654 // TClingClassInfo with the definition if we have it now.
6655 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6656 if (!oldDef || (def && def != oldDef)) {
6657 cl->ResetCaches();
6658 TClass::RemoveClassDeclId(cci->GetDeclId());
6659 if (def) {
6660 // It's a tag decl, not a namespace decl.
6661 cci->Init(*cci->GetType());
6662 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6663 }
6664 }
6665 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6666 cl->ResetCaches();
6667 // yes, this is almost a waste of time, but we do need to lookup
6668 // the 'type' corresponding to the TClass anyway in order to
6669 // preserve the opaque typedefs (Double32_t)
6670 if (!alias && def != nullptr)
6672 else
6674 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6675 // We now need to update the state and bits.
6676 if (cl->fState != TClass::kHasTClassInit) {
6677 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6679 }
6680 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6681 } else {
6682 delete ((TClingClassInfo *)cl->fClassInfo);
6683 cl->fClassInfo = nullptr;
6684 }
6685 }
6686}
6687
6688////////////////////////////////////////////////////////////////////////////////
6689/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6691{
6692 const TagDecl *td = dyn_cast<TagDecl>(ND);
6694 const NamedDecl *canon = nullptr;
6695
6696 std::string name;
6697 TagDecl* tdDef = nullptr;
6698 if (td) {
6699 canon = tdDef = td->getDefinition();
6700 // Let's pass the decl to the TClass only if it has a definition.
6701 if (!tdDef) return;
6702
6703 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6704 // Ignore incomplete definition.
6705 // Ignore declaration within a function.
6706 return;
6707 }
6708
6709 auto declName = tdDef->getNameAsString();
6710 // Check if we have registered the unqualified name into the list
6711 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6712 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6713 // the unqualified name is sufficient (and the fully qualified name might be
6714 // 'wrong' if there is difference in spelling in the template paramters (for example)
6716 // 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() );
6717 return;
6718 }
6719
6720 clang::QualType type(tdDef->getTypeForDecl(), 0);
6722 } else if (ns) {
6723 canon = ns->getCanonicalDecl();
6724 name = ND->getQualifiedNameAsString();
6725 } else {
6726 name = ND->getQualifiedNameAsString();
6727 }
6728
6729 // Supposedly we are being called while something is being
6730 // loaded ... let's now tell the autoloader to do the work
6731 // yet another time.
6733 // FIXME: There can be more than one TClass for a single decl.
6734 // for example vector<double> and vector<Double32_t>
6735 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6736 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6737 RefreshClassInfo(cl, canon, false);
6738 }
6739 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6740 // and update them too:
6741 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6742 // RefreshClassInfo(cl, tdDef, true);
6743}
6744
6745////////////////////////////////////////////////////////////////////////////////
6746/// No op: see TClingCallbacks
6747
6748void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6749{
6750}
6751
6752//______________________________________________________________________________
6753//FIXME: Factor out that function in TClass, because TClass does it already twice
6754void TCling::UpdateClassInfoWork(const char* item)
6755{
6756 // This is a no-op as part of the API.
6757 // TCling uses UpdateClassInfoWithDecl() instead.
6758}
6759
6760////////////////////////////////////////////////////////////////////////////////
6761/// Update all canvases at end the terminal input command.
6762
6764{
6765 TIter next(gROOT->GetListOfCanvases());
6766 TVirtualPad* canvas;
6767 while ((canvas = (TVirtualPad*)next())) {
6768 canvas->Update();
6769 }
6770}
6771
6772////////////////////////////////////////////////////////////////////////////////
6773
6774void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6775 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6776
6777 // If the transaction does not contain anything we can return earlier.
6778 if (!HandleNewTransaction(T)) return;
6779
6780 bool isTUTransaction = false;
6781 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6782 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6783 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6784 // The is the first transaction, we have to expose to meta
6785 // what's already in the AST.
6786 isTUTransaction = true;
6787 }
6788 }
6789
6790 std::set<const void*> TransactionDeclSet;
6791 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6792 const clang::Decl* WrapperFD = T.getWrapperFD();
6793 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6794 I != E; ++I) {
6795 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6796 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6797 continue;
6798
6799 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6800 DE = I->m_DGR.end(); DI != DE; ++DI) {
6801 if (*DI == WrapperFD)
6802 continue;
6803 TransactionDeclSet.insert(*DI);
6804 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6805 }
6806 }
6807 }
6808
6809 // The above might trigger more decls to be deserialized.
6810 // Thus the iteration over the deserialized decls must be last.
6811 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6812 E = T.deserialized_decls_end(); I != E; ++I) {
6813 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6814 DE = I->m_DGR.end(); DI != DE; ++DI)
6815 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6816 //FIXME: HandleNewDecl should take DeclGroupRef
6817 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6819 }
6820 }
6821
6822
6823 // When fully building the reflection info in TClass, a deserialization
6824 // could be triggered, which may result in request for building the
6825 // reflection info for the same TClass. This in turn will clear the caches
6826 // for the TClass in-flight and cause null ptr derefs.
6827 // FIXME: This is a quick fix, solving most of the issues. The actual
6828 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6829 // itself until the update is done.
6830 //
6831 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6832 std::vector<TClass*>::iterator it;
6834 ((TCling*)gCling)->GetModTClasses().begin(),
6835 ((TCling*)gCling)->GetModTClasses().end(),
6838
6839 // Lock the TClass for updates
6840 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6842 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6843 E = modifiedTClassesDiff.end(); I != E; ++I) {
6844 // Make sure the TClass has not been deleted.
6845 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6846 continue;
6847 }
6848 // Could trigger deserialization of decls.
6849 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6850 // Unlock the TClass for updates
6851 ((TCling*)gCling)->GetModTClasses().erase(*I);
6852
6853 }
6854}
6855
6856///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6857///
6858void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6859{
6861
6862 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6863 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6864 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6865 (TListOfEnums *)gROOT->GetListOfEnums());
6866
6867 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6868 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6869 I != E; ++I) {
6870 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6871 continue;
6872 if (I->m_Call == cling::Transaction::kCCINone) {
6874 ++iNested;
6875 continue;
6876 }
6877
6878 for (auto &D : I->m_DGR)
6880 }
6881}
6882
6883///\brief Invalidate cached TCling information for the given global declaration.
6884///
6886 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6887 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6888 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6889 (TListOfEnums *)gROOT->GetListOfEnums());
6891}
6892
6893///\brief Invalidate cached TCling information for the given declaration, and
6894/// removed it from the appropriate object list.
6895///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6896/// TListOfFunctionTemplates&, TListOfEnums&>
6897/// of pointers to the (global/class) object lists.
6898///\param[in] D - Decl to discard.
6899///
6903 TListOfEnums*> &Lists, const Decl *D) {
6904 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6905 return;
6906
6907 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6908 TListOfFunctions &LOF = *(std::get<1>(Lists));
6909 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6910 TListOfEnums &LOE = *(std::get<3>(Lists));
6911
6913 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6914 if (LODM.GetClass())
6915 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6916 else
6917 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6918 } else if (isa<FunctionDecl>(D)) {
6920 } else if (isa<FunctionTemplateDecl>(D)) {
6922 } else if (isa<EnumDecl>(D)) {
6923 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6924 if (!E)
6925 return;
6926
6927 // Try to invalidate enumerators (for unscoped enumerations).
6928 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6930 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6931
6933 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6935 return;
6936
6937 std::vector<TClass *> Classes;
6938 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6939 return;
6940 for (auto &C : Classes) {
6941 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6942 (TListOfFunctions *)C->GetListOfMethods(),
6943 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6944 (TListOfEnums *)C->GetListOfEnums());
6945 for (auto &I : cast<DeclContext>(D)->decls())
6947
6948 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6949 if (D->getKind() != Decl::Namespace
6950 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6951 C->ResetClassInfo();
6952 }
6953 }
6954}
6955
6956////////////////////////////////////////////////////////////////////////////////
6957// If an autoparse was done during a transaction and that it is rolled back,
6958// we need to make sure the next request for the same autoparse will be
6959// honored.
6960void TCling::TransactionRollback(const cling::Transaction &T) {
6961 auto const &triter = fTransactionHeadersMap.find(&T);
6962 if (triter != fTransactionHeadersMap.end()) {
6963 std::size_t normNameHash = triter->second;
6964
6966
6967 auto const &iter = fClassesHeadersMap.find(normNameHash);
6968 if (iter != fClassesHeadersMap.end()) {
6969 auto const &hNamesPtrs = iter->second;
6970 for (auto &hName : hNamesPtrs) {
6971 if (gDebug > 0) {
6972 Info("TransactionRollback",
6973 "Restoring ability to autoaparse: %s", hName);
6974 }
6976 }
6977 }
6978 }
6979}
6980
6981////////////////////////////////////////////////////////////////////////////////
6982
6983void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6984// R__LOCKGUARD_CLING(gInterpreterMutex);
6985// UpdateListOfLoadedSharedLibraries();
6986}
6987
6988////////////////////////////////////////////////////////////////////////////////
6989
6990void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6991 fPrevLoadedDynLibInfo = nullptr;
6992 fSharedLibs = "";
6993}
6994
6995////////////////////////////////////////////////////////////////////////////////
6996/// Return the list of shared libraries loaded into the process.
6997
7004
7005static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
7006{
7007 if (!cls || !*cls)
7008 return {};
7009
7010 using namespace clang;
7011 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7012 /*type*/ nullptr, /*instantiate*/ false)) {
7013 if (!D->isFromASTFile()) {
7014 if (gDebug > 5)
7015 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7016 return {};
7017 }
7018 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7019 llvm::DenseSet<Module *> &m_TopLevelModules;
7020
7021 public:
7022 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7023 void Collect(const Decl *D) { Visit(D); }
7024
7025 void VisitDecl(const Decl *D)
7026 {
7027 // FIXME: Such case is described ROOT-7765 where
7028 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7029 // They are specified as #includes in the LinkDef file. This leads to
7030 // generation of incomplete modulemap files and this logic fails to
7031 // compute the corresponding module of D.
7032 // FIXME: If we want to support such a case, we should not rely on
7033 // the contents of the modulemap but mangle D and look it up in the
7034 // .so files.
7035 if (!D->hasOwningModule())
7036 return;
7037 if (Module *M = D->getOwningModule()->getTopLevelModule())
7038 m_TopLevelModules.insert(M);
7039 }
7040
7042 {
7043 switch (TA.getKind()) {
7044 case TemplateArgument::Null:
7045 case TemplateArgument::Integral:
7046 case TemplateArgument::Pack:
7047 case TemplateArgument::NullPtr:
7048 case TemplateArgument::Expression:
7049 case TemplateArgument::Template:
7050 case TemplateArgument::TemplateExpansion: return;
7051 case TemplateArgument::Type:
7052 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7053 return Visit(TagTy->getDecl());
7054 return;
7055 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7056 }
7057 llvm_unreachable("Invalid TemplateArgument::Kind!");
7058 }
7059
7061 {
7062 if (CTSD->getOwningModule())
7063 VisitDecl(CTSD);
7064 else
7065 VisitDecl(CTSD->getSpecializedTemplate());
7066 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7067 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7069 }
7070 }
7071 };
7072
7073 llvm::DenseSet<Module *> TopLevelModules;
7075 m.Collect(D);
7076 std::string result;
7077 for (auto M : TopLevelModules) {
7078 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7079 // link declaration.
7080 if (!M->LinkLibraries.size())
7081 continue;
7082 // We have preloaded the Core module thus libCore.so
7083 if (M->Name == "Core")
7084 continue;
7085 assert(M->LinkLibraries.size() == 1);
7086 if (!result.empty())
7087 result += ' ';
7088 result += M->LinkLibraries[0].Library;
7089 }
7090 return result;
7091 }
7092 return {};
7093}
7094
7095////////////////////////////////////////////////////////////////////////////////
7096/// Get the list of shared libraries containing the code for class cls.
7097/// The first library in the list is the one containing the class, the
7098/// others are the libraries the first one depends on. Returns 0
7099/// in case the library is not found.
7100
7101const char* TCling::GetClassSharedLibs(const char* cls)
7102{
7103 if (fCxxModulesEnabled) {
7104 // Lock the interpreter mutex before interacting with cling.
7105 // TODO: Can we move this further deep? In principle the lock should be in
7106 // GetClassSharedLibsForModule, but it might be needed also for
7107 // getLookupHelper?
7109 llvm::StringRef className = cls;
7110 // If we get a class name containing lambda, we cannot parse it and we
7111 // can exit early.
7112 // FIXME: This works around a bug when we are instantiating a template
7113 // make_unique and the substitution fails. Seen in most of the dataframe
7114 // tests.
7115 if (className.contains("(lambda)"))
7116 return nullptr;
7117 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7119 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7120 std::string libs = GetClassSharedLibsForModule(cls, LH);
7121 if (!libs.empty()) {
7122 fAutoLoadLibStorage.push_back(libs);
7123 return fAutoLoadLibStorage.back().c_str();
7124 }
7125 }
7126
7127 if (!cls || !*cls) {
7128 return nullptr;
7129 }
7130 // lookup class to find list of libraries
7131 if (fMapfile) {
7132 TEnvRec* libs_record = nullptr;
7134 if (libs_record) {
7135 const char* libs = libs_record->GetValue();
7136 return (*libs) ? libs : nullptr;
7137 }
7138 else {
7139 // Try the old format...
7140 TString c = TString("Library.") + cls;
7141 // convert "::" to "@@", we used "@@" because TEnv
7142 // considers "::" a terminator
7143 c.ReplaceAll("::", "@@");
7144 // convert "-" to " ", since class names may have
7145 // blanks and TEnv considers a blank a terminator
7146 c.ReplaceAll(" ", "-");
7147 // Use TEnv::Lookup here as the rootmap file must start with Library.
7148 // and do not support using any stars (so we do not need to waste time
7149 // with the search made by TEnv::GetValue).
7150 TEnvRec* libs_record = nullptr;
7152 if (libs_record) {
7153 const char* libs = libs_record->GetValue();
7154 return (*libs) ? libs : nullptr;
7155 }
7156 }
7157 }
7158 return nullptr;
7159}
7160
7161/// This interface returns a list of dependent libraries in the form:
7162/// lib libA.so libB.so libC.so. The first library is the library we are
7163/// searching dependencies for.
7164/// Note: In order to speed up the search, we display the dependencies of the
7165/// libraries which are not yet loaded. For instance, if libB.so was already
7166/// loaded the list would contain: lib libA.so libC.so.
7167static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7168 cling::Interpreter *interp,
7169 bool skipLoadedLibs = true)
7170{
7171 TString LibFullPath(lib);
7172 if (!llvm::sys::path::is_absolute(lib)) {
7173 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7174 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7175 return "";
7176 }
7177 } else {
7178 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7179 lib = llvm::sys::path::filename(lib).str();
7180 }
7181
7182 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7183 if (!ObjF) {
7184 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7185 return "";
7186 }
7187
7188 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7189
7190 std::set<string> DedupSet;
7191 std::string Result = lib + ' ';
7192 for (const auto &S : BinObjFile->symbols()) {
7193 uint32_t Flags = llvm::cantFail(S.getFlags());
7194 // Skip defined symbols: we have them.
7195 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7196 continue;
7197 // Skip undefined weak symbols: if we don't have them we won't need them.
7198 // `__gmon_start__` being a typical example.
7199 if (Flags & llvm::object::SymbolRef::SF_Weak)
7200 continue;
7201 llvm::Expected<StringRef> SymNameErr = S.getName();
7202 if (!SymNameErr) {
7203 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7204 continue;
7205 }
7206 llvm::StringRef SymName = SymNameErr.get();
7207 if (SymName.empty())
7208 continue;
7209
7210 if (BinObjFile->isELF()) {
7211 // Skip the symbols which are part of the C/C++ runtime and have a
7212 // fixed library version. See binutils ld VERSION. Those reside in
7213 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7214 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7215 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7216 continue;
7217
7218 // Those are 'weak undefined' symbols produced by gcc. We can
7219 // ignore them.
7220 // FIXME: It is unclear whether we can ignore all weak undefined
7221 // symbols:
7222 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7223 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7224 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7225 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7226 if (SymName == RegisterClasses ||
7229 continue;
7230 }
7231
7232 // If we can find the address of the symbol, we have loaded it. Skip.
7233 if (skipLoadedLibs) {
7235 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7236 continue;
7237 }
7238
7240 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7241 // The expected output is just filename without the full path, which
7242 // is not very accurate, because our Dyld implementation might find
7243 // a match in location a/b/c.so and if we return just c.so ROOT might
7244 // resolve it to y/z/c.so and there we might not be ABI compatible.
7245 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7246 if (!found.empty()) {
7247 std::string cand = llvm::sys::path::filename(found).str();
7248 if (!DedupSet.insert(cand).second)
7249 continue;
7250
7251 Result += cand + ' ';
7252 }
7253 }
7254
7255 return Result;
7256}
7257
7258static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7259{
7260 // Check if we have parsed a rootmap file.
7261 llvm::SmallString<256> rootmapName;
7262 if (!lib.startswith("lib"))
7263 rootmapName.append("lib");
7264
7265 rootmapName.append(llvm::sys::path::filename(lib));
7266 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7267
7268 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7269 return true;
7270
7271 // Perform a last resort by dropping the lib prefix.
7272 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7273 if (rootmapNameNoLib.consume_front("lib"))
7274 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7275
7276 return false;
7277}
7278
7279static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7280{
7281 if (gCling->HasPCMForLibrary(lib.data()))
7282 return true;
7283
7284 return hasParsedRootmapForLibrary(lib);
7285}
7286
7287////////////////////////////////////////////////////////////////////////////////
7288/// Get the list a libraries on which the specified lib depends. The
7289/// returned string contains as first element the lib itself.
7290/// Returns 0 in case the lib does not exist or does not have
7291/// any dependencies. If useDyld is true, we iterate through all available
7292/// libraries and try to construct the dependency chain by resolving each
7293/// symbol.
7294
7295const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7296{
7297 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7298 return nullptr;
7299
7300 if (!hasParsedRootmapForLibrary(lib)) {
7301 llvm::SmallString<512> rootmapName(lib);
7302 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7303 if (llvm::sys::fs::exists(rootmapName)) {
7304 if (gDebug > 0)
7305 Info("Load", "loading %s", rootmapName.c_str());
7306 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7307 }
7308 }
7309
7310 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7311 if (gDebug > 0)
7312 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7313 }
7314
7315 if (useDyld) {
7317 if (!libs.empty()) {
7318 fAutoLoadLibStorage.push_back(libs);
7319 return fAutoLoadLibStorage.back().c_str();
7320 }
7321 }
7322
7323 if (!fMapfile || !lib || !lib[0]) {
7324 return nullptr;
7325 }
7326 TString libname(lib);
7327 Ssiz_t idx = libname.Last('.');
7328 if (idx != kNPOS) {
7329 libname.Remove(idx);
7330 }
7331 TEnvRec* rec;
7332 TIter next(fMapfile->GetTable());
7333 size_t len = libname.Length();
7334 while ((rec = (TEnvRec*) next())) {
7335 const char* libs = rec->GetValue();
7336 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7337 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7338 return libs;
7339 }
7340 }
7341 return nullptr;
7342}
7343
7344////////////////////////////////////////////////////////////////////////////////
7345/// If error messages are disabled, the interpreter should suppress its
7346/// failures and warning messages from stdout.
7347
7349{
7350#if defined(R__MUST_REVISIT)
7351#if R__MUST_REVISIT(6,2)
7352 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7353#endif
7354#endif
7355 return kTRUE;
7356}
7357
7358////////////////////////////////////////////////////////////////////////////////
7359/// If error messages are disabled, the interpreter should suppress its
7360/// failures and warning messages from stdout. Return the previous state.
7361
7363{
7364#if defined(R__MUST_REVISIT)
7365#if R__MUST_REVISIT(6,2)
7366 Warning("SetErrorMessages", "Interface not available yet.");
7367#endif
7368#endif
7370}
7371
7372////////////////////////////////////////////////////////////////////////////////
7373/// Refresh the list of include paths known to the interpreter and return it
7374/// with -I prepended.
7375
7377{
7379
7380 fIncludePath = "";
7381
7382 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7383 //false - no system header, true - with flags.
7384 fInterpreter->GetIncludePaths(includePaths, false, true);
7385 if (const size_t nPaths = includePaths.size()) {
7386 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7387
7388 for (size_t i = 0; i < nPaths; i += 2) {
7389 if (i)
7390 fIncludePath.Append(' ');
7391 fIncludePath.Append(includePaths[i].c_str());
7392
7393 if (includePaths[i] != "-I")
7394 fIncludePath.Append(' ');
7395 fIncludePath.Append('"');
7397 fIncludePath.Append('"');
7398 }
7399 }
7400
7401 return fIncludePath;
7402}
7403
7404////////////////////////////////////////////////////////////////////////////////
7405/// Return the directory containing CINT's stl cintdlls.
7406
7407const char* TCling::GetSTLIncludePath() const
7408{
7409 return "";
7410}
7411
7412//______________________________________________________________________________
7413// M I S C
7414//______________________________________________________________________________
7415
7416int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7417{
7418 // Interface to cling function
7419 return 0;
7420}
7421
7422////////////////////////////////////////////////////////////////////////////////
7423/// Interface to cling function
7424
7426{
7427 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7428
7429 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7430 //false - no system header, true - with flags.
7431 fInterpreter->GetIncludePaths(includePaths, false, true);
7432 if (const size_t nPaths = includePaths.size()) {
7433 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7434
7435 std::string allIncludes("include path:");
7436 for (size_t i = 0; i < nPaths; i += 2) {
7437 allIncludes += ' ';
7439
7440 if (includePaths[i] != "-I")
7441 allIncludes += ' ';
7442 allIncludes += includePaths[i + 1];
7443 }
7444
7445 fprintf(fout, "%s\n", allIncludes.c_str());
7446 }
7447
7448 return 0;
7449}
7450
7451////////////////////////////////////////////////////////////////////////////////
7452/// Interface to cling function
7453
7454void* TCling::FindSym(const char* entry) const
7455{
7457 return fInterpreter->getAddressOfGlobal(entry);
7458}
7459
7460////////////////////////////////////////////////////////////////////////////////
7461/// Let the interpreter issue a generic error, and set its error state.
7462
7463void TCling::GenericError(const char* error) const
7464{
7465#if defined(R__MUST_REVISIT)
7466#if R__MUST_REVISIT(6,2)
7467 Warning("GenericError","Interface not available yet.");
7468#endif
7469#endif
7470}
7471
7472////////////////////////////////////////////////////////////////////////////////
7473/// This routines used to return the address of the internal wrapper
7474/// function (of the interpreter) that was used to call *all* the
7475/// interpreted functions that were bytecode compiled (no longer
7476/// interpreted line by line). In Cling, there is no such
7477/// wrapper function.
7478/// In practice this routines was use to decipher whether the
7479/// pointer returns by InterfaceMethod could be used to uniquely
7480/// represent the function. In Cling if the function is in a
7481/// useable state (its compiled version is available), this is
7482/// always the case.
7483/// See TClass::GetMethod.
7484
7486{
7487 return 0;
7488}
7489
7490////////////////////////////////////////////////////////////////////////////////
7491/// Interface to cling function
7492
7494{
7495#if defined(R__MUST_REVISIT)
7496#if R__MUST_REVISIT(6,2)
7497 Warning("GetSecurityError", "Interface not available yet.");
7498#endif
7499#endif
7500 return 0;
7501}
7502
7503////////////////////////////////////////////////////////////////////////////////
7504/// Load a source file or library called path into the interpreter.
7505
7506int TCling::LoadFile(const char* path) const
7507{
7508 // Modifying the interpreter state needs locking.
7510 cling::Interpreter::CompilationResult compRes;
7511 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7512 return compRes == cling::Interpreter::kFailure;
7513}
7514
7515////////////////////////////////////////////////////////////////////////////////
7516/// Load the declarations from text into the interpreter.
7517/// Note that this cannot be (top level) statements; text must contain
7518/// top level declarations.
7519/// Returns true on success, false on failure.
7520
7521Bool_t TCling::LoadText(const char* text) const
7522{
7523 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7524}
7525
7526////////////////////////////////////////////////////////////////////////////////
7527/// Interface to cling function
7528
7529const char* TCling::MapCppName(const char* name) const
7530{
7531 TTHREAD_TLS_DECL(std::string,buffer);
7533 return buffer.c_str(); // NOLINT
7534}
7535
7536////////////////////////////////////////////////////////////////////////////////
7537/// [Place holder for Mutex Lock]
7538/// Provide the interpreter with a way to
7539/// acquire a lock used to protect critical section
7540/// of its code (non-thread safe parts).
7541
7542void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7543{
7544 // nothing to do for now.
7545}
7546
7547////////////////////////////////////////////////////////////////////////////////
7548/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7549/// release a lock used to protect critical section
7550/// of its code (non-thread safe parts).
7551
7552void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7553{
7554 // nothing to do for now.
7555}
7556
7557////////////////////////////////////////////////////////////////////////////////
7558/// Returns if class AutoLoading is currently enabled.
7559
7561{
7562 if (IsFromRootCling())
7563 return false;
7564 if (!fClingCallbacks)
7565 return false;
7567}
7568
7569////////////////////////////////////////////////////////////////////////////////
7570/// Enable/Disable the AutoLoading of libraries.
7571/// Returns the old value, i.e whether it was enabled or not.
7572
7574{
7575 // If no state change is required, exit early.
7576 // FIXME: In future we probably want to complain if we made a request which
7577 // was with the same state as before in order to catch programming errors.
7578 if ((bool) autoload == IsClassAutoLoadingEnabled())
7579 return autoload;
7580
7581 assert(fClingCallbacks && "We must have callbacks!");
7584 return oldVal;
7585}
7586
7587////////////////////////////////////////////////////////////////////////////////
7588/// Enable/Disable the Autoparsing of headers.
7589/// Returns the old value, i.e whether it was enabled or not.
7590
7597
7598////////////////////////////////////////////////////////////////////////////////
7599/// Suspend the Autoparsing of headers.
7600/// Returns the old value, i.e whether it was suspended or not.
7601
7608
7609////////////////////////////////////////////////////////////////////////////////
7610/// Set a callback to receive error messages.
7611
7613{
7614#if defined(R__MUST_REVISIT)
7615#if R__MUST_REVISIT(6,2)
7616 Warning("SetErrmsgcallback", "Interface not available yet.");
7617#endif
7618#endif
7619}
7620
7622{
7623 if (enable) {
7625 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7626 fInterpreter->getCI()->getLangOpts(),
7627 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7628 if (Level == clang::DiagnosticsEngine::Warning) {
7629 ::Warning("cling", "%s", Info.c_str());
7630 } else if (Level == clang::DiagnosticsEngine::Error
7631 || Level == clang::DiagnosticsEngine::Fatal) {
7632 ::Error("cling", "%s", Info.c_str());
7633 } else {
7634 ::Info("cling", "%s", Info.c_str());
7635 }
7636 });
7637 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7638 } else {
7639 fInterpreter->replaceDiagnosticConsumer(nullptr);
7640 }
7641}
7642
7643
7644////////////////////////////////////////////////////////////////////////////////
7645/// Create / close a scope for temporaries. No-op for cling; use
7646/// cling::Value instead.
7647
7648void TCling::SetTempLevel(int val) const
7649{
7650}
7651
7652////////////////////////////////////////////////////////////////////////////////
7653
7654int TCling::UnloadFile(const char* path) const
7655{
7656 // Modifying the interpreter state needs locking.
7658 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7659 std::string canonical = DLM->lookupLibrary(path);
7660 if (canonical.empty()) {
7661 canonical = path;
7662 }
7663 // Unload a shared library or a source file.
7664 cling::Interpreter::CompilationResult compRes;
7665 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7666 return compRes == cling::Interpreter::kFailure;
7667}
7668
7669std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7670 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7671}
7672
7673////////////////////////////////////////////////////////////////////////////////
7674/// The call to Cling's tab complition.
7675
7676void TCling::CodeComplete(const std::string& line, size_t& cursor,
7677 std::vector<std::string>& completions)
7678{
7679 fInterpreter->codeComplete(line, cursor, completions);
7680}
7681
7682////////////////////////////////////////////////////////////////////////////////
7683/// Get the interpreter value corresponding to the statement.
7685{
7687
7688 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7689 auto compRes = fInterpreter->evaluate(code, *V);
7690 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7691}
7692
7693////////////////////////////////////////////////////////////////////////////////
7694
7696{
7697 using namespace cling;
7698 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7700}
7701
7702////////////////////////////////////////////////////////////////////////////////
7703/// Register value as a temporary, extending its lifetime to that of the
7704/// interpreter. This is needed for TCling's compatibility interfaces
7705/// returning long - the address of the temporary objects.
7706/// As such, "simple" types don't need to be stored; they are returned by
7707/// value; only pointers / references / objects need to be stored.
7708
7709void TCling::RegisterTemporary(const cling::Value& value)
7710{
7711 if (value.isValid() && value.needsManagedAllocation()) {
7713 fTemporaries->push_back(value);
7714 }
7715}
7716
7717////////////////////////////////////////////////////////////////////////////////
7718/// If the interpreter encounters Name, check whether that is an object ROOT
7719/// could retrieve. To not re-read objects from disk, cache the name/object
7720/// pair for a given LookupCtx.
7721
7723{
7724 // The call to FindSpecialObject might induces any kind of use
7725 // of the interpreter ... (library loading, function calling, etc.)
7726 // ... and we _know_ we are in the middle of parsing, so let's make
7727 // sure to save the state and then restore it.
7728
7729 if (gDirectory) {
7731 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7732 auto iSpecObj = iSpecObjMap->second.find(Name);
7733 if (iSpecObj != iSpecObjMap->second.end()) {
7735 return iSpecObj->second;
7736 }
7737 }
7738 }
7739
7740 // Save state of the PP
7741 Sema &SemaR = fInterpreter->getSema();
7742 ASTContext& C = SemaR.getASTContext();
7743 Preprocessor &PP = SemaR.getPreprocessor();
7744 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7745 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7746 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7747 // After we have saved the token reset the current one to something which
7748 // is safe (semi colon usually means empty decl)
7749 Token& Tok = const_cast<Token&>(P.getCurToken());
7750 Tok.setKind(tok::semi);
7751
7752 // We can't PushDeclContext, because we go up and the routine that pops
7753 // the DeclContext assumes that we drill down always.
7754 // We have to be on the global context. At that point we are in a
7755 // wrapper function so the parent context must be the global.
7756 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7757 SemaR.TUScope);
7758
7759 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7760 if (specObj) {
7761 if (!LookupCtx) {
7762 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7763 } else {
7765 }
7766 }
7767 return specObj;
7768}
7769
7770////////////////////////////////////////////////////////////////////////////////
7771/// Inject function as a friend into klass.
7772/// With function being f in void f() {new N::PrivKlass(); } this enables
7773/// I/O of non-public classes.
7774
7775void TCling::AddFriendToClass(clang::FunctionDecl* function,
7776 clang::CXXRecordDecl* klass) const
7777{
7778 using namespace clang;
7779 ASTContext& Ctx = klass->getASTContext();
7780 FriendDecl::FriendUnion friendUnion(function);
7781 // one dummy object for the source location
7783 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7784 klass->pushFriendDecl(friendDecl);
7785}
7786
7787//______________________________________________________________________________
7788//
7789// DeclId getter.
7790//
7791
7792////////////////////////////////////////////////////////////////////////////////
7793/// Return a unique identifier of the declaration represented by the
7794/// CallFunc
7795
7797{
7798 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7799 return nullptr;
7800}
7801
7802////////////////////////////////////////////////////////////////////////////////
7803/// Return a (almost) unique identifier of the declaration represented by the
7804/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7805/// when the underlying class is a template instance involving one of the
7806/// opaque typedef.
7807
7809{
7810 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7811 return nullptr;
7812}
7813
7814////////////////////////////////////////////////////////////////////////////////
7815/// Return a unique identifier of the declaration represented by the
7816/// MethodInfo
7817
7819{
7820 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7821 return nullptr;
7822}
7823
7824////////////////////////////////////////////////////////////////////////////////
7825/// Return a unique identifier of the declaration represented by the
7826/// MethodInfo
7827
7829{
7830 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7831 return nullptr;
7832}
7833
7834////////////////////////////////////////////////////////////////////////////////
7835/// Return a unique identifier of the declaration represented by the
7836/// TypedefInfo
7837
7839{
7840 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7841 return nullptr;
7842}
7843
7844//______________________________________________________________________________
7845//
7846// CallFunc interface
7847//
7848
7849////////////////////////////////////////////////////////////////////////////////
7850
7852{
7853 delete (TClingCallFunc*) func;
7854}
7855
7856////////////////////////////////////////////////////////////////////////////////
7857
7858void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7859{
7860 TClingCallFunc* f = (TClingCallFunc*) func;
7861 f->Exec(address);
7862}
7863
7864////////////////////////////////////////////////////////////////////////////////
7865
7866void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7867{
7868 TClingCallFunc* f = (TClingCallFunc*) func;
7869 f->Exec(address, &val);
7870}
7871
7872////////////////////////////////////////////////////////////////////////////////
7873
7874void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7875{
7876 TClingCallFunc* f = (TClingCallFunc*) func;
7877 f->ExecWithReturn(address, ret);
7878}
7879
7880////////////////////////////////////////////////////////////////////////////////
7881
7883 const void* args[] /*=0*/,
7884 int nargs /*=0*/,
7885 void* ret/*=0*/) const
7886{
7887 TClingCallFunc* f = (TClingCallFunc*) func;
7888 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7889}
7890
7891////////////////////////////////////////////////////////////////////////////////
7892
7894{
7895 TClingCallFunc* f = (TClingCallFunc*) func;
7896 return f->ExecInt(address);
7897}
7898
7899////////////////////////////////////////////////////////////////////////////////
7900
7902{
7903 TClingCallFunc* f = (TClingCallFunc*) func;
7904 return f->ExecInt64(address);
7905}
7906
7907////////////////////////////////////////////////////////////////////////////////
7908
7910{
7911 TClingCallFunc* f = (TClingCallFunc*) func;
7912 return f->ExecDouble(address);
7913}
7914
7915////////////////////////////////////////////////////////////////////////////////
7916
7922
7923////////////////////////////////////////////////////////////////////////////////
7924
7926{
7927 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7928}
7929
7930////////////////////////////////////////////////////////////////////////////////
7931
7933{
7934 TClingCallFunc* f = (TClingCallFunc*) func;
7935 return (MethodInfo_t*) f->FactoryMethod();
7936}
7937
7938////////////////////////////////////////////////////////////////////////////////
7939
7941{
7942 TClingCallFunc* f = (TClingCallFunc*) func;
7943 f->IgnoreExtraArgs(ignore);
7944}
7945
7946////////////////////////////////////////////////////////////////////////////////
7947
7949{
7951 TClingCallFunc* f = (TClingCallFunc*) func;
7952 f->Init();
7953}
7954
7955////////////////////////////////////////////////////////////////////////////////
7956
7958{
7959 TClingCallFunc* f = (TClingCallFunc*) func;
7960 return f->IsValid();
7961}
7962
7963////////////////////////////////////////////////////////////////////////////////
7964
7967{
7968 TClingCallFunc* f = (TClingCallFunc*) func;
7969 return f->IFacePtr();
7970}
7971
7972////////////////////////////////////////////////////////////////////////////////
7973
7975{
7976 TClingCallFunc* f = (TClingCallFunc*) func;
7977 f->ResetArg();
7978}
7979
7980////////////////////////////////////////////////////////////////////////////////
7981
7983{
7984 TClingCallFunc* f = (TClingCallFunc*) func;
7985 f->SetArg(param);
7986}
7987
7988////////////////////////////////////////////////////////////////////////////////
7989
7991{
7992 TClingCallFunc* f = (TClingCallFunc*) func;
7993 f->SetArg(param);
7994}
7995
7996////////////////////////////////////////////////////////////////////////////////
7997
7999{
8000 TClingCallFunc* f = (TClingCallFunc*) func;
8001 f->SetArg(param);
8002}
8003
8004////////////////////////////////////////////////////////////////////////////////
8005
8007{
8008 TClingCallFunc* f = (TClingCallFunc*) func;
8009 f->SetArg(param);
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013
8015{
8016 TClingCallFunc* f = (TClingCallFunc*) func;
8017 f->SetArg(param);
8018}
8019
8020////////////////////////////////////////////////////////////////////////////////
8021
8023{
8024 TClingCallFunc* f = (TClingCallFunc*) func;
8025 f->SetArg(param);
8026}
8027
8028////////////////////////////////////////////////////////////////////////////////
8029
8031{
8032 TClingCallFunc* f = (TClingCallFunc*) func;
8033 f->SetArgArray(paramArr, nparam);
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037
8038void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8039{
8040 TClingCallFunc* f = (TClingCallFunc*) func;
8041 f->SetArgs(param);
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045
8046void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8047{
8048 TClingCallFunc* f = (TClingCallFunc*) func;
8050 f->SetFunc(ci, method, params, offset);
8051}
8052
8053////////////////////////////////////////////////////////////////////////////////
8054
8055void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8056{
8057 TClingCallFunc* f = (TClingCallFunc*) func;
8059 f->SetFunc(ci, method, params, objectIsConst, offset);
8060}
8061////////////////////////////////////////////////////////////////////////////////
8062
8063void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8064{
8065 TClingCallFunc* f = (TClingCallFunc*) func;
8067 f->SetFunc(minfo);
8068}
8069
8070////////////////////////////////////////////////////////////////////////////////
8071/// Interface to cling function
8072
8073void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8074{
8075 TClingCallFunc* f = (TClingCallFunc*) func;
8077 f->SetFuncProto(ci, method, proto, offset, mode);
8078}
8079
8080////////////////////////////////////////////////////////////////////////////////
8081/// Interface to cling function
8082
8083void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8084{
8085 TClingCallFunc* f = (TClingCallFunc*) func;
8087 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8088}
8089
8090////////////////////////////////////////////////////////////////////////////////
8091/// Interface to cling function
8092
8093void 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
8094{
8095 TClingCallFunc* f = (TClingCallFunc*) func;
8097 llvm::SmallVector<clang::QualType, 4> funcProto;
8098 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8099 iter != end; ++iter) {
8100 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8101 }
8102 f->SetFuncProto(ci, method, funcProto, offset, mode);
8103}
8104
8105////////////////////////////////////////////////////////////////////////////////
8106/// Interface to cling function
8107
8108void 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
8109{
8110 TClingCallFunc* f = (TClingCallFunc*) func;
8112 llvm::SmallVector<clang::QualType, 4> funcProto;
8113 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8114 iter != end; ++iter) {
8115 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8116 }
8117 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8118}
8119
8121{
8122 TClingCallFunc *f = (TClingCallFunc *)func;
8123 std::string wrapper_name;
8124 std::string wrapper;
8125 f->get_wrapper_code(wrapper_name, wrapper);
8126 return wrapper;
8127}
8128
8129//______________________________________________________________________________
8130//
8131// ClassInfo interface
8132//
8133
8134////////////////////////////////////////////////////////////////////////////////
8135/// Return true if the entity pointed to by 'declid' is declared in
8136/// the context described by 'info'. If info is null, look into the
8137/// global scope (translation unit scope).
8138
8140{
8141 if (!declid)
8142 return kFALSE;
8143
8144 const clang::DeclContext *ctxt = nullptr;
8145 if (info) {
8146 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8147 } else {
8148 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8149 }
8150 if (!ctxt)
8151 return kFALSE;
8152
8153 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8154 if (!decl)
8155 return kFALSE;
8156
8157 const clang::DeclContext *declDC = decl->getDeclContext();
8158 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8159 while (true) {
8160 if (declDC->isTransparentContext()) {
8161 declDC = declDC->getParent();
8162 continue;
8163 }
8164 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8165 if (declRD->isAnonymousStructOrUnion()) {
8166 declDC = declRD->getParent();
8167 continue;
8168 }
8169 }
8170 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8171 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8172 declDC = declNS->getParent();
8173 continue;
8174 }
8175 }
8176 break;
8177 }
8178
8179 return declDC->Equals(ctxt);
8180}
8181
8182////////////////////////////////////////////////////////////////////////////////
8183
8189
8190////////////////////////////////////////////////////////////////////////////////
8191
8193{
8194 delete (TClingClassInfo*) cinfo;
8195}
8196
8197////////////////////////////////////////////////////////////////////////////////
8198
8204
8205////////////////////////////////////////////////////////////////////////////////
8206
8212
8213////////////////////////////////////////////////////////////////////////////////
8214
8220
8221////////////////////////////////////////////////////////////////////////////////
8222
8228
8229////////////////////////////////////////////////////////////////////////////////
8230
8235
8236////////////////////////////////////////////////////////////////////////////////
8237
8243
8249
8250
8251////////////////////////////////////////////////////////////////////////////////
8252
8253int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8254{
8256 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8257}
8258
8259////////////////////////////////////////////////////////////////////////////////
8260
8266
8267////////////////////////////////////////////////////////////////////////////////
8268
8270{
8272 return TClinginfo->HasMethod(name);
8273}
8274
8275////////////////////////////////////////////////////////////////////////////////
8276
8283
8284////////////////////////////////////////////////////////////////////////////////
8285
8287{
8290 TClinginfo->Init(tagnum);
8291}
8292
8293////////////////////////////////////////////////////////////////////////////////
8294
8296{
8298 return TClinginfo->IsBase(name);
8299}
8300
8301////////////////////////////////////////////////////////////////////////////////
8302
8303bool TCling::ClassInfo_IsEnum(const char* name) const
8304{
8306}
8307
8308////////////////////////////////////////////////////////////////////////////////
8309
8315
8316
8317////////////////////////////////////////////////////////////////////////////////
8318
8324
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8329{
8331 return TClinginfo->IsLoaded();
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8337{
8339 return TClinginfo->IsValid();
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8345{
8347 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8353{
8355 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8356}
8357
8358////////////////////////////////////////////////////////////////////////////////
8359
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8373
8374////////////////////////////////////////////////////////////////////////////////
8375
8381
8382////////////////////////////////////////////////////////////////////////////////
8383
8385{
8387 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8388}
8389
8390////////////////////////////////////////////////////////////////////////////////
8391
8397
8398////////////////////////////////////////////////////////////////////////////////
8399
8405
8406////////////////////////////////////////////////////////////////////////////////
8407
8413
8414////////////////////////////////////////////////////////////////////////////////
8415
8421
8422////////////////////////////////////////////////////////////////////////////////
8423
8425{
8427 return TClinginfo->FileName();
8428}
8429
8430////////////////////////////////////////////////////////////////////////////////
8431
8433{
8435 TTHREAD_TLS_DECL(std::string,output);
8436 TClinginfo->FullName(output,*fNormalizedCtxt);
8437 return output.c_str(); // NOLINT
8438}
8439
8440////////////////////////////////////////////////////////////////////////////////
8441
8443{
8445 return TClinginfo->Name();
8446}
8447
8448////////////////////////////////////////////////////////////////////////////////
8449
8451{
8453 return TClinginfo->Title();
8454}
8455
8456////////////////////////////////////////////////////////////////////////////////
8457
8459{
8461 return TClinginfo->TmpltName();
8462}
8463
8464
8465
8466//______________________________________________________________________________
8467//
8468// BaseClassInfo interface
8469//
8470
8471////////////////////////////////////////////////////////////////////////////////
8472
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8486
8487////////////////////////////////////////////////////////////////////////////////
8488
8497
8498////////////////////////////////////////////////////////////////////////////////
8499
8505
8506////////////////////////////////////////////////////////////////////////////////
8507
8513
8514////////////////////////////////////////////////////////////////////////////////
8515
8521
8522////////////////////////////////////////////////////////////////////////////////
8523
8525{
8528 // Offset to the class itself.
8529 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8530 return 0;
8531 }
8532 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8533}
8534
8535////////////////////////////////////////////////////////////////////////////////
8536
8542
8543////////////////////////////////////////////////////////////////////////////////
8544
8550
8551////////////////////////////////////////////////////////////////////////////////
8552
8558
8559////////////////////////////////////////////////////////////////////////////////
8560
8562{
8564 TTHREAD_TLS_DECL(std::string,output);
8565 TClinginfo->FullName(output,*fNormalizedCtxt);
8566 return output.c_str(); // NOLINT
8567}
8568
8569////////////////////////////////////////////////////////////////////////////////
8570
8576
8577////////////////////////////////////////////////////////////////////////////////
8578
8584
8585//______________________________________________________________________________
8586//
8587// DataMemberInfo interface
8588//
8589
8590////////////////////////////////////////////////////////////////////////////////
8591
8597
8598////////////////////////////////////////////////////////////////////////////////
8599
8604
8605////////////////////////////////////////////////////////////////////////////////
8606
8613
8614////////////////////////////////////////////////////////////////////////////////
8615
8617{
8619 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8620 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625
8631
8632////////////////////////////////////////////////////////////////////////////////
8633
8639
8640////////////////////////////////////////////////////////////////////////////////
8641
8647
8648////////////////////////////////////////////////////////////////////////////////
8649
8655
8656////////////////////////////////////////////////////////////////////////////////
8657
8663
8664////////////////////////////////////////////////////////////////////////////////
8665
8671
8672////////////////////////////////////////////////////////////////////////////////
8673
8679
8680////////////////////////////////////////////////////////////////////////////////
8681
8687
8688////////////////////////////////////////////////////////////////////////////////
8689
8695
8696////////////////////////////////////////////////////////////////////////////////
8697
8703
8704////////////////////////////////////////////////////////////////////////////////
8705
8711
8712////////////////////////////////////////////////////////////////////////////////
8713
8719
8720////////////////////////////////////////////////////////////////////////////////
8721
8723{
8724 TTHREAD_TLS_DECL(std::string,result);
8725
8727 result = TClinginfo->ValidArrayIndex().str();
8728 return result.c_str(); // NOLINT
8729}
8730
8731////////////////////////////////////////////////////////////////////////////////
8732
8734{
8735 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8736 ASTContext &C = decl->getASTContext();
8737 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8738}
8739
8740//______________________________________________________________________________
8741//
8742// Function Template interface
8743//
8744
8745////////////////////////////////////////////////////////////////////////////////
8746
8747static void ConstructorName(std::string &name, const clang::Decl *decl,
8748 cling::Interpreter &interp,
8750{
8751 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8752 if (!td) return;
8753
8754 clang::QualType qualType(td->getTypeForDecl(),0);
8756 unsigned int level = 0;
8757 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8758 if (name[cursor] == '>') ++level;
8759 else if (name[cursor] == '<' && level) --level;
8760 else if (level == 0 && name[cursor] == ':') {
8761 name.erase(0,cursor+1);
8762 break;
8763 }
8764 }
8765}
8766
8767////////////////////////////////////////////////////////////////////////////////
8768
8769void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8770{
8771 output.clear();
8772
8773 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8774 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8775 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8776 }
8777 if (!FD) {
8778 Error("GetFunctionName", "NULL Decl!");
8779 return;
8780 }
8781
8782 // For using-decls, show "Derived", not "Base", i.e. use the
8783 // name of the decl context of the UsingShadowDecl (aka `decl`)
8784 // not the name of FD's decl context.
8785 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8786 {
8788
8789 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8790 {
8792 output.insert(output.begin(), '~');
8793 } else {
8794 llvm::raw_string_ostream stream(output);
8795 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8796 // Don't trigger fopen of the source file to count lines:
8797 printPolicy.AnonymousTagLocations = false;
8798 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8799 }
8800}
8801
8802////////////////////////////////////////////////////////////////////////////////
8803/// Return a unique identifier of the declaration represented by the
8804/// FuncTempInfo
8805
8810
8811////////////////////////////////////////////////////////////////////////////////
8812/// Delete the FuncTempInfo_t
8813
8815{
8816 // Currently the address of ft_info is actually the decl itself,
8817 // so we have nothing to do.
8818}
8819
8820////////////////////////////////////////////////////////////////////////////////
8821/// Construct a FuncTempInfo_t
8822
8824{
8825 // Currently the address of ft_info is actually the decl itself,
8826 // so we have nothing to do.
8827
8828 return (FuncTempInfo_t*)const_cast<void*>(declid);
8829}
8830
8831////////////////////////////////////////////////////////////////////////////////
8832/// Construct a FuncTempInfo_t
8833
8835{
8836 // Currently the address of ft_info is actually the decl itself,
8837 // so we have nothing to do.
8838
8839 return (FuncTempInfo_t*)ft_info;
8840}
8841
8842////////////////////////////////////////////////////////////////////////////////
8843/// Check validity of a FuncTempInfo_t
8844
8846{
8847 // Currently the address of ft_info is actually the decl itself,
8848 // so we have nothing to do.
8849
8850 return t_info != nullptr;
8851}
8852
8853////////////////////////////////////////////////////////////////////////////////
8854/// Return the maximum number of template arguments of the
8855/// function template described by ft_info.
8856
8858{
8859 if (!ft_info) return 0;
8860 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8861 return ft->getTemplateParameters()->size();
8862}
8863
8864////////////////////////////////////////////////////////////////////////////////
8865/// Return the number of required template arguments of the
8866/// function template described by ft_info.
8867
8869{
8870 if (!ft_info) return 0;
8871 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8872 return ft->getTemplateParameters()->getMinRequiredArguments();
8873}
8874
8875////////////////////////////////////////////////////////////////////////////////
8876/// Return the property of the function template.
8877
8879{
8880 if (!ft_info) return 0;
8881
8882 long property = 0L;
8883 property |= kIsCompiled;
8884
8885 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8886
8887 switch (ft->getAccess()) {
8888 case clang::AS_public:
8889 property |= kIsPublic;
8890 break;
8891 case clang::AS_protected:
8892 property |= kIsProtected;
8893 break;
8894 case clang::AS_private:
8895 property |= kIsPrivate;
8896 break;
8897 case clang::AS_none:
8898 if (ft->getDeclContext()->isNamespace())
8900 break;
8901 default:
8902 // IMPOSSIBLE
8903 assert(false && "Unexpected value for the access property value in Clang");
8904 break;
8905 }
8906
8907 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8908 if (const clang::CXXMethodDecl *md =
8909 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8910 if (md->getMethodQualifiers().hasConst()) {
8911 property |= kIsConstant | kIsConstMethod;
8912 }
8913 if (md->isVirtual()) {
8914 property |= kIsVirtual;
8915 }
8916 if (md->isPure()) {
8917 property |= kIsPureVirtual;
8918 }
8919 if (const clang::CXXConstructorDecl *cd =
8920 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8921 if (cd->isExplicit()) {
8922 property |= kIsExplicit;
8923 }
8924 }
8925 else if (const clang::CXXConversionDecl *cd =
8926 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8927 if (cd->isExplicit()) {
8928 property |= kIsExplicit;
8929 }
8930 }
8931 }
8932 return property;
8933}
8934
8935////////////////////////////////////////////////////////////////////////////////
8936/// Return the property not already defined in Property
8937/// See TDictionary's EFunctionProperty
8938
8940{
8941 if (!ft_info) return 0;
8942
8943 long property = 0L;
8944 property |= kIsCompiled;
8945
8946 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8947 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8948
8949 if (fd->isOverloadedOperator())
8951 if (llvm::isa<clang::CXXConversionDecl>(fd))
8953 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8955 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8957 if (fd->isInlined())
8959 return property;
8960}
8961
8962////////////////////////////////////////////////////////////////////////////////
8963/// Return the name of this function template.
8964
8966{
8967 output.Clear();
8968 if (!ft_info) return;
8969 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8970 std::string buf;
8971 GetFunctionName(ft->getTemplatedDecl(), buf);
8972 output = buf;
8973}
8974
8975////////////////////////////////////////////////////////////////////////////////
8976/// Return the comments associates with this function template.
8977
8979{
8980 output.Clear();
8981 if (!ft_info) return;
8982 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8983
8984 // Iterate over the redeclarations, we can have multiple definitions in the
8985 // redecl chain (came from merging of pcms).
8988 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8989 output = A->getAnnotation().str();
8990 return;
8991 }
8992 }
8993 if (!ft->isFromASTFile()) {
8994 // Try to get the comment from the header file if present
8995 // but not for decls from AST file, where rootcling would have
8996 // created an annotation
8998 }
8999}
9000
9001
9002//______________________________________________________________________________
9003//
9004// MethodInfo interface
9005//
9006
9007////////////////////////////////////////////////////////////////////////////////
9008/// Interface to cling function
9009
9010void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9011{
9012 delete(TClingMethodInfo*) minfo;
9013}
9014
9015////////////////////////////////////////////////////////////////////////////////
9016
9018{
9020 // The next call locks the interpreter mutex.
9021 info->CreateSignature(signature);
9022}
9023
9024////////////////////////////////////////////////////////////////////////////////
9025
9026MethodInfo_t* TCling::MethodInfo_Factory() const
9027{
9029 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033
9035{
9037 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9038}
9039
9040////////////////////////////////////////////////////////////////////////////////
9041
9043{
9044 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9046 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9047}
9048
9049////////////////////////////////////////////////////////////////////////////////
9050
9051MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9052{
9053 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9054}
9055
9056////////////////////////////////////////////////////////////////////////////////
9057
9059{
9061 // The next call locks the interpreter mutex.
9062 return info->InterfaceMethod();
9063}
9064
9065////////////////////////////////////////////////////////////////////////////////
9066
9067bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9068{
9070 return info->IsValid();
9071}
9072
9073////////////////////////////////////////////////////////////////////////////////
9074
9075int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9076{
9078 return info->NArg();
9079}
9080
9081////////////////////////////////////////////////////////////////////////////////
9082
9084{
9086 return info->NDefaultArg();
9087}
9088
9089////////////////////////////////////////////////////////////////////////////////
9090
9091int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9092{
9094 return info->Next();
9095}
9096
9097////////////////////////////////////////////////////////////////////////////////
9098
9100{
9102 // The next call locks the interpreter mutex.
9103 return info->Property();
9104}
9105
9106////////////////////////////////////////////////////////////////////////////////
9107
9109{
9111 // The next call locks the interpreter mutex.
9112 return info->ExtraProperty();
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116
9118{
9120 // The next call locks the interpreter mutex.
9121 return (TypeInfo_t*)info->Type();
9122}
9123
9124////////////////////////////////////////////////////////////////////////////////
9125
9126const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9127{
9130 // The next call locks the interpreter mutex.
9131 mangled_name = info->GetMangledName();
9132 return mangled_name;
9133}
9134
9135////////////////////////////////////////////////////////////////////////////////
9136
9137const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9138{
9140 // The next call locks the interpreter mutex.
9141 return info->GetPrototype();
9142}
9143
9144////////////////////////////////////////////////////////////////////////////////
9145
9146const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9147{
9149 // The next call locks the interpreter mutex.
9150 return info->Name();
9151}
9152
9153////////////////////////////////////////////////////////////////////////////////
9154
9155const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9156{
9158 // The next call locks the interpreter mutex.
9159 return info->TypeName();
9160}
9161
9162////////////////////////////////////////////////////////////////////////////////
9163
9164std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9165{
9167 // The next part locks the interpreter mutex.
9168 if (info && info->IsValid())
9169 return info->Type()->NormalizedName(*fNormalizedCtxt);
9170 else
9171 return "";
9172}
9173
9174////////////////////////////////////////////////////////////////////////////////
9175
9176const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9177{
9179 // The next call locks the interpreter mutex.
9180 return info->Title();
9181}
9182
9183////////////////////////////////////////////////////////////////////////////////
9184
9186{
9187 if (func) {
9188 return MethodInfo_MethodCallReturnType(func->fInfo);
9189 } else {
9190 return EReturnType::kOther;
9191 }
9192}
9193
9194////////////////////////////////////////////////////////////////////////////////
9195
9197{
9199 if (info && info->IsValid()) {
9200 TClingTypeInfo *typeinfo = info->Type();
9201 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9202 if (QT->isEnumeralType()) {
9203 return EReturnType::kLong;
9204 } else if (QT->isPointerType()) {
9205 // Look for char*
9206 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9207 if ( QT->isCharType() ) {
9208 return EReturnType::kString;
9209 } else {
9210 return EReturnType::kOther;
9211 }
9212 } else if ( QT->isFloatingType() ) {
9213 int sz = typeinfo->Size();
9214 if (sz == 4 || sz == 8) {
9215 // Support only float and double.
9216 return EReturnType::kDouble;
9217 } else {
9218 return EReturnType::kOther;
9219 }
9220 } else if ( QT->isIntegerType() ) {
9221 int sz = typeinfo->Size();
9222 if (sz <= 8) {
9223 // Support only up to long long ... but
9224 // FIXME the TMethodCall::Execute only
9225 // return long (4 bytes) ...
9226 // The v5 implementation of TMethodCall::ReturnType
9227 // was not making the distinction so we let it go
9228 // as is for now, but we really need to upgrade
9229 // TMethodCall::Execute ...
9230 return EReturnType::kLong;
9231 } else {
9232 return EReturnType::kOther;
9233 }
9234 } else {
9235 return EReturnType::kOther;
9236 }
9237 } else {
9238 return EReturnType::kOther;
9239 }
9240}
9241
9242//______________________________________________________________________________
9243//
9244// MethodArgInfo interface
9245//
9246
9247////////////////////////////////////////////////////////////////////////////////
9248
9253
9254////////////////////////////////////////////////////////////////////////////////
9255
9261
9262////////////////////////////////////////////////////////////////////////////////
9263
9269
9270////////////////////////////////////////////////////////////////////////////////
9271
9277
9278////////////////////////////////////////////////////////////////////////////////
9279
9285
9286////////////////////////////////////////////////////////////////////////////////
9287
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9305{
9307 return info->DefaultValue();
9308}
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9313{
9315 return info->Name();
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319
9321{
9323 return info->TypeName();
9324}
9325
9326////////////////////////////////////////////////////////////////////////////////
9327
9329{
9331 return info->Type()->NormalizedName(*fNormalizedCtxt);
9332}
9333
9334////////////////////////////////////////////////////////////////////////////////
9335
9341
9342//______________________________________________________________________________
9343//
9344// TypeInfo interface
9345//
9346
9347////////////////////////////////////////////////////////////////////////////////
9348
9350{
9351 delete (TClingTypeInfo*) tinfo;
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355
9361
9362////////////////////////////////////////////////////////////////////////////////
9363
9369
9370////////////////////////////////////////////////////////////////////////////////
9371
9376
9377////////////////////////////////////////////////////////////////////////////////
9378
9385
9386////////////////////////////////////////////////////////////////////////////////
9387
9389{
9391 return TClinginfo->IsValid();
9392}
9393
9394////////////////////////////////////////////////////////////////////////////////
9395
9397{
9399 return TClinginfo->Name();
9400}
9401
9402////////////////////////////////////////////////////////////////////////////////
9403
9409
9410////////////////////////////////////////////////////////////////////////////////
9411
9413{
9415 return TClinginfo->RefType();
9416}
9417
9418////////////////////////////////////////////////////////////////////////////////
9419
9421{
9423 return TClinginfo->Size();
9424}
9425
9426////////////////////////////////////////////////////////////////////////////////
9427
9429{
9431 return TClinginfo->TrueName(*fNormalizedCtxt);
9432}
9433
9434////////////////////////////////////////////////////////////////////////////////
9435
9437{
9439 return TClinginfo->QualTypePtr();
9440}
9441
9442
9443//______________________________________________________________________________
9444//
9445// TypedefInfo interface
9446//
9447
9448////////////////////////////////////////////////////////////////////////////////
9449
9454
9455////////////////////////////////////////////////////////////////////////////////
9456
9462
9463////////////////////////////////////////////////////////////////////////////////
9464
9470
9471////////////////////////////////////////////////////////////////////////////////
9472
9477
9478////////////////////////////////////////////////////////////////////////////////
9479
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9495
9496////////////////////////////////////////////////////////////////////////////////
9497
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9511
9512////////////////////////////////////////////////////////////////////////////////
9513
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9527
9528////////////////////////////////////////////////////////////////////////////////
9529
9531{
9533 return TClinginfo->Name();
9534}
9535
9536////////////////////////////////////////////////////////////////////////////////
9537
9539{
9541 return TClinginfo->Title();
9542}
9543
9544////////////////////////////////////////////////////////////////////////////////
9545
9546bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9547{
9548 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9549 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9550 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9551}
9552
9553////////////////////////////////////////////////////////////////////////////////
9554
9555bool TCling::IsIntegerType(const void * QualTypePtr) const
9556{
9557 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9558 return QT->hasIntegerRepresentation();
9559}
9560
9561////////////////////////////////////////////////////////////////////////////////
9562
9563bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9564{
9565 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9566 return QT->hasSignedIntegerRepresentation();
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570
9571bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9572{
9573 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9574 return QT->hasUnsignedIntegerRepresentation();
9575}
9576
9577////////////////////////////////////////////////////////////////////////////////
9578
9579bool TCling::IsFloatingType(const void * QualTypePtr) const
9580{
9581 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9582 return QT->hasFloatingRepresentation();
9583}
9584
9585////////////////////////////////////////////////////////////////////////////////
9586
9587bool TCling::IsPointerType(const void * QualTypePtr) const
9588{
9589 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9590 return QT->hasPointerRepresentation();
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594
9595bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9596{
9597 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9598 return QT->isVoidPointerType();
9599}
9600
9601////////////////////////////////////////////////////////////////////////////////
9602
9604{
9605 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9606 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9607}
9608
9609////////////////////////////////////////////////////////////////////////////////
9610
9612{
9613 if (!fInitialMutex) {
9615 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9616 }
9617 fInitialMutex.fState = mtx->GetStateBefore();
9618 }
9619 // We will "forget" this lock once we backed out of all interpreter frames.
9620 // Here we are entering one, so ++.
9622}
9623
9624////////////////////////////////////////////////////////////////////////////////
9625
9627{
9628 if (!fInitialMutex)
9629 return;
9630 if (fInitialMutex.fRecurseCount == 0) {
9631 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9632 }
9633 else if (--fInitialMutex.fRecurseCount == 0) {
9634 // We have returned from all interpreter frames. Reset the initial lock state.
9635 fInitialMutex.fState.reset();
9636 }
9637}
9638
9639////////////////////////////////////////////////////////////////////////////////
9640/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9641
9643{
9644 if (gInterpreterMutex) {
9645 if (delta) {
9646 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9647 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9648 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9649 // Now that we have the lock, update the global
9650 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9651 std::swap(fInitialMutex, typedDelta->fInitialState);
9652 } else {
9653 // This case happens when EnableThreadSafety is first called from
9654 // the interpreter function we just handled.
9655 // Since thread safety was not enabled at the time we rewound, there was
9656 // no lock taken and even-though we should be locking the rest of this
9657 // interpreter handling/modifying code (since there might be threads in
9658 // flight), we can't because there would not be any lock guard to release the
9659 // locks
9661 Error("ApplyToInterpreterMutex",
9662 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9663 "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.");
9664 }
9665 }
9666}
9667
9668////////////////////////////////////////////////////////////////////////////////
9669/// Reset the interpreter lock to the state it had before interpreter-related
9670/// calls happened.
9671
9673{
9674 if (fInitialMutex) {
9675 // Need to start a new recurse count.
9676 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9677 std::swap(uniqueP->fInitialState, fInitialMutex);
9678 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9679 return uniqueP.release();
9680 }
9682 return nullptr;
9683}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
RooAbsReal & function()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1308
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7258
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:7005
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:574
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:901
R__EXTERN int optind
Definition TCling.cxx:317
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:368
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:569
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:557
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:333
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:224
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3918
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:3142
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:3960
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:3936
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:588
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:389
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:215
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:644
#define R__DLLEXPORT
Definition TCling.cxx:151
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:360
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:233
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:623
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1039
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1192
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8747
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:7167
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
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:6345
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5525
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:218
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:600
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program.
Definition TCling.cxx:1061
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:639
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:616
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7279
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:651
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
@ kIsNotReacheable
Definition TDictionary.h:87
#define gDirectory
Definition TDirectory.h:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx: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
const_iterator begin() const
const_iterator end() const
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3466
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2887
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
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3425
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
@ kLoading
Definition TClass.h:332
@ kUnloading
Definition TClass.h:332
TObjArray * fStreamerInfo
Definition TClass.h:198
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
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
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 * Name() const
Emulation of the CINT CallFunc class.
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
static bool IsEnum(cling::Interpreter *interp, const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
TClingMethodInfo GetMethod(const char *fname) const
const clang::ValueDecl * GetDataMember(const char *name) const
Emulation of the CINT DataMemberInfo class.
virtual const char * Name() const
virtual bool IsValid() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
Emulation of the CINT MethodInfo class.
TDictionary::DeclId_t GetDeclId() const
Emulation of the CINT TypeInfo class.
Emulation of the CINT TypedefInfo class.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1015
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1023
std::string fContent
Definition TCling.h:619
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6217
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9304
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8310
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9396
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9058
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4408
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3898
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9490
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6278
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7948
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:3661
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6581
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7463
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7874
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9117
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7851
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:7506
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3737
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8733
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:496
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Invalidate cached TCling information for the given declaration, and removed it from the appropriate o...
Definition TCling.cxx:6900
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9099
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4455
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8344
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8666
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7591
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:4502
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3782
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8336
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6774
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9412
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4384
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8223
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9146
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8480
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7521
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7295
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9196
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7722
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3573
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9067
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8823
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9356
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7560
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6885
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7684
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7669
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3361
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9538
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:8073
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5668
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:6536
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9603
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:4520
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:7775
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:8500
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6648
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7925
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7909
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7974
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5476
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3185
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3885
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7940
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9642
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6604
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:4736
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:8139
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3151
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:7485
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8592
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9336
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8626
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3678
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:5541
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8360
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7612
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9280
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9420
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3796
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7493
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7648
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:8857
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:5168
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9457
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9595
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:8408
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9320
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:5416
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8650
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9530
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8473
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9108
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3565
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7101
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8834
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8642
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8845
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:8295
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3696
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8690
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4963
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8030
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8120
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9672
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9312
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3160
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9480
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8714
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7893
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3098
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:7542
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:7362
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7932
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9571
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9473
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:5061
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:9328
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:4845
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9296
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9514
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7882
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:5213
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:6754
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3528
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9498
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:5020
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9379
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7602
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8682
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8450
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8706
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5491
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9563
void ForgetMutexState() final
Definition TCling.cxx:9626
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9091
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8184
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9010
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9249
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8607
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8215
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:6123
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6011
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8277
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8545
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7901
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8400
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8524
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:5398
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7348
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7425
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6960
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8878
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9428
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6029
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7695
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6998
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9288
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9611
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9404
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9137
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:8868
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:6169
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9017
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4362
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6983
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:8634
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8303
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9083
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4511
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5938
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:7621
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9126
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9555
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:5123
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8368
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7416
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8769
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4536
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7407
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9272
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8516
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:4190
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7454
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3428
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9349
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9075
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4954
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9185
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:5146
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:4975
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9176
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8579
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:3111
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8561
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8038
int UnloadFile(const char *path) const final
Definition TCling.cxx:7654
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4054
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7858
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9587
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9579
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8939
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7957
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8571
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8722
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4557
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:4885
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5246
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8328
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8416
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8537
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8046
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4491
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8424
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8978
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8458
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3872
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:6640
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:3753
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7676
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:3767
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7529
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3598
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5950
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3905
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8600
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:5429
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:4529
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:6091
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9051
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7966
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9256
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6748
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:5042
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8192
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8319
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8814
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:5190
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3811
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8658
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7917
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9026
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8674
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3090
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:7552
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:9450
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3721
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9522
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7573
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8432
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:6394
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9155
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7982
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7376
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6858
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6690
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9546
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:8253
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:4784
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:8965
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9388
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:9164
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8442
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4567
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8261
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3134
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9372
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9436
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8269
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8207
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:8698
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:3912
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9506
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:3582
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:5002
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6763
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5754
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8553
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6990
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:175
@ kNone
Definition TEnum.h:48
@ kAutoload
Definition TEnum.h:49
Definition TEnv.h:86
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
THashList * GetTable() const
Definition TEnv.h:140
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:793
virtual void SetRcName(const char *name)
Definition TEnv.h:145
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:592
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:736
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:547
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:53
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * Remove(TObject *obj) override
Remove object from the list.
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
This class defines an abstract interface to a generic command line interpreter.
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
virtual const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A doubly linked list.
Definition TList.h:38
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
TNamed()
Definition TNamed.h:36
An array of TObjects.
Definition TObjArray.h:31
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h: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
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual TClass * IsA() const
Definition TObject.h:240
void MakeZombie()
Definition TObject.h:53
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx: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! Used by rootcling to inject interpreter arguments through a C-interface layer.
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
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Bool_t IsNull() const
Definition TString.h:414
TString & Append(const char *cs)
Definition TString.h:572
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1665
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3973
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4258
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1071
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1538
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2489
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1795
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2034
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition TSystem.cxx:2836
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:871
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1649
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:887
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2020
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TLine * line
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#define 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.
bool IsUniquePtr(std::string_view name)
Definition TClassEdit.h:182
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:135
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:157
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:162
A read-only memory range which we do not control.
Definition TMemFile.h:23
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static void output()