Logo ROOT   6.18/05
Reference Guide
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
22#include "TClingBaseClassInfo.h"
23#include "TClingCallFunc.h"
24#include "TClingClassInfo.h"
26#include "TClingMethodArgInfo.h"
27#include "TClingMethodInfo.h"
28#include "TClingTypedefInfo.h"
29#include "TClingTypeInfo.h"
30#include "TClingValue.h"
31
32#include "TROOT.h"
33#include "TApplication.h"
34#include "TGlobal.h"
35#include "TDataType.h"
36#include "TClass.h"
37#include "TClassEdit.h"
38#include "TClassTable.h"
39#include "TClingCallbacks.h"
40#include "TBaseClass.h"
41#include "TDataMember.h"
42#include "TMemberInspector.h"
43#include "TMethod.h"
44#include "TMethodArg.h"
45#include "TFunctionTemplate.h"
46#include "TObjArray.h"
47#include "TObjString.h"
48#include "TString.h"
49#include "THashList.h"
50#include "TOrdCollection.h"
51#include "TVirtualPad.h"
52#include "TSystem.h"
53#include "TVirtualMutex.h"
54#include "TError.h"
55#include "TEnv.h"
56#include "TEnum.h"
57#include "TEnumConstant.h"
58#include "THashTable.h"
60#include "RConfigure.h"
61#include "compiledata.h"
62#include "TClingUtils.h"
65#include "TListOfDataMembers.h"
66#include "TListOfEnums.h"
68#include "TListOfFunctions.h"
70#include "TProtoClass.h"
71#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
72#include "ThreadLocalStorage.h"
73#include "TFile.h"
74#include "TKey.h"
75#include "ClingRAII.h"
76
77#include "clang/AST/ASTContext.h"
78#include "clang/AST/Decl.h"
79#include "clang/AST/DeclarationName.h"
80#include "clang/AST/GlobalDecl.h"
81#include "clang/AST/RecordLayout.h"
82#include "clang/AST/RecursiveASTVisitor.h"
83#include "clang/AST/Type.h"
84#include "clang/Basic/SourceLocation.h"
85#include "clang/Basic/Specifiers.h"
86#include "clang/Basic/TargetInfo.h"
87#include "clang/CodeGen/ModuleBuilder.h"
88#include "clang/Frontend/CompilerInstance.h"
89#include "clang/Frontend/FrontendDiagnostic.h"
90#include "clang/Lex/HeaderSearch.h"
91#include "clang/Lex/Preprocessor.h"
92#include "clang/Lex/PreprocessorOptions.h"
93#include "clang/Sema/Lookup.h"
94#include "clang/Sema/Sema.h"
95#include "clang/Parse/Parser.h"
96
97#include "cling/Interpreter/ClangInternalState.h"
98#include "cling/Interpreter/DynamicLibraryManager.h"
99#include "cling/Interpreter/Interpreter.h"
100#include "cling/Interpreter/LookupHelper.h"
101#include "cling/Interpreter/Value.h"
102#include "cling/Interpreter/Transaction.h"
103#include "cling/MetaProcessor/MetaProcessor.h"
104#include "cling/Utils/AST.h"
105#include "cling/Utils/ParserStateRAII.h"
106#include "cling/Utils/SourceNormalization.h"
107#include "cling/Interpreter/Exception.h"
108
109#include "llvm/IR/GlobalValue.h"
110#include "llvm/IR/Module.h"
111
112#include "llvm/Support/DynamicLibrary.h"
113#include "llvm/Support/raw_ostream.h"
114#include "llvm/Support/Path.h"
115#include "llvm/Support/Process.h"
116#include "llvm/Object/ObjectFile.h"
117#include "llvm/Support/FileSystem.h"
118#include "llvm/Object/SymbolicFile.h"
119
120#include <algorithm>
121#include <iostream>
122#include <cassert>
123#include <map>
124#include <set>
125#include <stdexcept>
126#include <stdint.h>
127#include <fstream>
128#include <sstream>
129#include <string>
130#include <tuple>
131#include <typeinfo>
132#include <unordered_map>
133#include <utility>
134#include <vector>
135#include <functional>
136
137#ifndef R__WIN32
138#include <cxxabi.h>
139#define R__DLLEXPORT __attribute__ ((visibility ("default")))
140#include <sys/stat.h>
141#endif
142#include <limits.h>
143#include <stdio.h>
144
145#ifdef __APPLE__
146#include <dlfcn.h>
147#include <mach-o/dyld.h>
148#include <mach-o/loader.h>
149#endif // __APPLE__
150
151#ifdef R__UNIX
152#include <dlfcn.h>
153#endif
154
155#if defined(__CYGWIN__)
156#include <sys/cygwin.h>
157#define HMODULE void *
158extern "C" {
159 __declspec(dllimport) void * __stdcall GetCurrentProcess();
160 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
161 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
162}
163#endif
164
165// Fragment copied from LLVM's raw_ostream.cpp
166#if defined(_MSC_VER)
167#ifndef STDIN_FILENO
168# define STDIN_FILENO 0
169#endif
170#ifndef STDOUT_FILENO
171# define STDOUT_FILENO 1
172#endif
173#ifndef STDERR_FILENO
174# define STDERR_FILENO 2
175#endif
176#ifndef R__WIN32
177//#if defined(HAVE_UNISTD_H)
178# include <unistd.h>
179//#endif
180#else
181#include "Windows4Root.h"
182#include <Psapi.h>
183#undef GetModuleFileName
184#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
185#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
186#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
187#define dlclose(library) ::FreeLibrary((HMODULE)library)
188#define R__DLLEXPORT __declspec(dllexport)
189#endif
190#endif
191
192//______________________________________________________________________________
193// Infrastructure to detect and react to libCling being teared down.
194//
195namespace {
196 class TCling_UnloadMarker {
197 public:
198 ~TCling_UnloadMarker() {
201 }
202 }
203 };
204 static TCling_UnloadMarker gTClingUnloadMarker;
205}
206
207
208
209//______________________________________________________________________________
210// These functions are helpers for debugging issues with non-LLVMDEV builds.
211//
212R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
213 return D->getDeclContext();
214}
215R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
216 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
217}
218R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
219 return llvm::dyn_cast<clang::RecordDecl>(DC);
220}
221R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
222 return DC->dumpDeclContext();
223}
224R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
225 return D->dump();
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
228 return FD->dump();
229}
231 return ((clang::Decl*)D)->dump();
232}
234 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
235 std::string name;
236 {
237 llvm::raw_string_ostream OS(name);
238 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
239 true /*Qualified*/);
240 }
241 printf("%s\n", name.c_str());
242 }
243}
244//______________________________________________________________________________
245// These functions are helpers for testing issues directly rather than
246// relying on side effects.
247// This is used for the test for ROOT-7462/ROOT-6070
249 return D->isInvalidDecl();
250}
251R__DLLEXPORT bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
252 TClingClassInfo *info( (TClingClassInfo*) input);
253 assert(info && info->IsValid());
254 return info->GetDecl()->isInvalidDecl();
255}
256
257using namespace std;
258using namespace clang;
259using namespace ROOT;
260
261namespace {
262 static const std::string gInterpreterClassDef = R"ICF(
263#undef ClassDef
264#define ClassDef(name, id) \
265_ClassDefInterp_(name,id,virtual,) \
266static int DeclFileLine() { return __LINE__; }
267#undef ClassDefNV
268#define ClassDefNV(name, id) \
269_ClassDefInterp_(name,id,,) \
270static int DeclFileLine() { return __LINE__; }
271#undef ClassDefOverride
272#define ClassDefOverride(name, id) \
273_ClassDefInterp_(name,id,,override) \
274static int DeclFileLine() { return __LINE__; }
275)ICF";
276
277 static const std::string gNonInterpreterClassDef = R"ICF(
278#define __ROOTCLING__ 1
279#undef ClassDef
280#define ClassDef(name,id) \
281_ClassDefOutline_(name,id,virtual,) \
282static int DeclFileLine() { return __LINE__; }
283#undef ClassDefNV
284#define ClassDefNV(name, id)\
285_ClassDefOutline_(name,id,,)\
286static int DeclFileLine() { return __LINE__; }
287#undef ClassDefOverride
288#define ClassDefOverride(name, id)\
289_ClassDefOutline_(name,id,,override)\
290static int DeclFileLine() { return __LINE__; }
291)ICF";
292
293// The macros below use ::Error, so let's ensure it is included
294 static const std::string gClassDefInterpMacro = R"ICF(
295#include "TError.h"
296
297#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
298private: \
299public: \
300 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
301 static const char *Class_Name() { return #name; } \
302 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
303 static Version_t Class_Version() { return id; } \
304 static TClass *Dictionary() { return 0; } \
305 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
306 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
307 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
308 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
309 static const char *DeclFileName() { return __FILE__; } \
310 static int ImplFileLine() { return 0; } \
311 static const char *ImplFileName() { return __FILE__; }
312)ICF";
313}
315
316// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
317// ROOT (which uses rtti)
318
319////////////////////////////////////////////////////////////////////////////////
320/// Print a StackTrace!
321
322extern "C"
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
329
330extern "C" void TCling__RestoreInterpreterMutex(void *delta)
331{
332 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
337/// which is extracted by error messages we get from callback from cling. Return true
338/// when the missing library was autoloaded.
339
340extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
341{
342 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// Reset the interpreter lock to the state it had before interpreter-related
347/// calls happened.
348
350{
351 return ((TCling*)gCling)->RewindInterpreterMutex();
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Lock the interpreter.
356
358{
359 if (gInterpreterMutex) {
361 }
362 return nullptr;
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Unlock the interpreter.
367
369{
370 if (gInterpreterMutex) {
372 }
373}
374
375////////////////////////////////////////////////////////////////////////////////
376/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
377
378static void TCling__UpdateClassInfo(const NamedDecl* TD)
379{
380 static Bool_t entered = kFALSE;
381 static vector<const NamedDecl*> updateList;
382 Bool_t topLevel;
383
384 if (entered) topLevel = kFALSE;
385 else {
386 entered = kTRUE;
387 topLevel = kTRUE;
388 }
389 if (topLevel) {
390 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
391 } else {
392 // If we are called indirectly from within another call to
393 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
394 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
395 // This allows for the dictionary to be fully populated when we actually
396 // update the TClass object. The updating of the TClass sometimes
397 // (STL containers and when there is an emulated class) forces the building
398 // of the TClass object's real data (which needs the dictionary info).
399 updateList.push_back(TD);
400 }
401 if (topLevel) {
402 while (!updateList.empty()) {
403 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
404 updateList.pop_back();
405 }
406 entered = kFALSE;
407 }
408}
409
410void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
411 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
412 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
413 // Add the constants to the enum type.
414 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
415 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
416 // Get name of the enum type.
417 std::string constbuf;
418 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
419 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
420 llvm::raw_string_ostream stream(constbuf);
421 // Don't trigger fopen of the source file to count lines:
422 Policy.AnonymousTagLocations = false;
423 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
424 }
425 const char* constantName = constbuf.c_str();
426
427 // Get value of the constant.
428 Long64_t value;
429 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
430 if (valAPSInt.isSigned()) {
431 value = valAPSInt.getSExtValue();
432 } else {
433 value = valAPSInt.getZExtValue();
434 }
435
436 // Create the TEnumConstant or update it if existing
437 TEnumConstant* enumConstant = nullptr;
438 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
439 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(fInterpreter, *EDI, tcCInfo);
440 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
441 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
442 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
443 } else {
444 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
445 }
446
447 // Add the global constants to the list of Globals.
448 if (!cl) {
449 TCollection* globals = gROOT->GetListOfGlobals(false);
450 if (!globals->FindObject(constantName)) {
451 globals->Add(enumConstant);
452 }
453 }
454 }
455 }
456}
457
458TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
459{
460 // Handle new enum declaration for either global and nested enums.
461
462 // Create the enum type.
463 TEnum* enumType = 0;
464 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
465 std::string buf;
466 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
467 // Get name of the enum type.
468 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
469 llvm::raw_string_ostream stream(buf);
470 // Don't trigger fopen of the source file to count lines:
471 Policy.AnonymousTagLocations = false;
472 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
473 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
474 }
475 if (buf.empty()) {
476 return 0;
477 }
478 const char* name = buf.c_str();
479 enumType = new TEnum(name, VD, cl);
480 UpdateEnumConstants(enumType, cl);
481
482 return enumType;
483}
484
485void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
486 // Handle new declaration.
487 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
488
489 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
490
491 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
492 && !dyn_cast<clang::RecordDecl>(D)) return;
493
494 if (isa<clang::FunctionDecl>(D->getDeclContext())
495 || isa<clang::TagDecl>(D->getDeclContext()))
496 return;
497
498 // Don't list templates.
499 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
500 if (RD->getDescribedClassTemplate())
501 return;
502 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
503 if (FD->getDescribedFunctionTemplate())
504 return;
505 }
506
507 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
508 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
510 }
511 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
512
513 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
514 // Mostly just for EnumDecl (the other TagDecl are handled
515 // by the 'RecordDecl' if statement.
517 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
519 }
520
521 // We care about declarations on the global scope.
522 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
523 return;
524
525 // Enums are lazyly created, thus we don not need to handle them here.
526 if (isa<EnumDecl>(ND))
527 return;
528
529 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
530 // scope.
531 if (!(isa<VarDecl>(ND)))
532 return;
533
534 // Skip if already in the list.
535 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
536 return;
537
538 // Put the global constants and global enums in the corresponding lists.
539 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
541 cast<ValueDecl>(ND), 0)));
542 }
543}
544
545extern "C"
546void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt*& normCtxt)
547{
548 // We are sure in this context of the type of the interpreter
549 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
550}
551
552extern "C"
553void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
554
555 ((TCling*)gCling)->UpdateListsOnCommitted(T);
556}
557
558extern "C"
559void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
560
561 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
562}
563
564extern "C"
565void TCling__TransactionRollback(const cling::Transaction &T) {
566
567 ((TCling*)gCling)->TransactionRollback(T);
568}
569
570extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
571 const char* canonicalName) {
572
573 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
574}
575
576extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
577 const char* canonicalName) {
578
579 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
580}
581
582
583extern "C"
584TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
585 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
586}
587
588extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
589 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
590}
591
592extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
593 const char* argv[])
594{
595 cling::DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(interpLibHandle);
596 return new TCling("C++", "cling C++ Interpreter", argv);
597}
598
600{
601 delete interp;
602}
603
604// Load library containing specified class. Returns 0 in case of error
605// and 1 in case if success.
606extern "C" int TCling__AutoLoadCallback(const char* className)
607{
608 return ((TCling*)gCling)->AutoLoad(className);
609}
610
611extern "C" int TCling__AutoParseCallback(const char* className)
612{
613 return ((TCling*)gCling)->AutoParse(className);
614}
615
616extern "C" const char* TCling__GetClassSharedLibs(const char* className)
617{
618 return ((TCling*)gCling)->GetClassSharedLibs(className);
619}
620
621// // Returns 0 for failure 1 for success
622// extern "C" int TCling__IsAutoLoadNamespaceCandidate(const char* name)
623// {
624// return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(name);
625// }
626
627// Returns 0 for failure 1 for success
628extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
629{
630 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
631}
632
633extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
634{
635 string file(fileName);
636 string opt(options);
637 return gSystem->CompileMacro(file.c_str(), opt.c_str());
638}
639
640extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
641 string &args, string &io, string &fname)
642{
643 string file(fileName);
644 TString f, amode, arguments, aclicio;
645 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
646 mode = amode.Data(); args = arguments.Data();
647 io = aclicio.Data(); fname = f.Data();
648}
649
650// Implemented in TClingCallbacks.
651extern "C" void TCling__FindLoadedLibraries(std::vector<std::pair<uint32_t, std::string>> &sLibraries,
652 std::vector<std::string> &sPaths,
653 cling::Interpreter &interpreter, bool searchSystem);
654
655//______________________________________________________________________________
656//
657//
658//
659
660#ifdef R__WIN32
661extern "C" {
662 char *__unDName(char *demangled, const char *mangled, int out_len,
663 void * (* pAlloc )(size_t), void (* pFree )(void *),
664 unsigned short int flags);
665}
666#endif
667
668////////////////////////////////////////////////////////////////////////////////
669/// Find a template decl within N nested namespaces, 0<=N<inf
670/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
671/// by the namespace. Example: ns1::ns2::..::nsN::myTemplate
672/// Returns nullptr in case of error
673
674static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
675{
676 using namespace clang;
677 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
678 return FindTemplateInNamespace(*nsd->decls_begin());
679 }
680
681 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
682 return ctd;
683 }
684
685 return nullptr; // something went wrong.
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Autoload a library provided the mangled name of a missing symbol.
690
691void* llvmLazyFunctionCreator(const std::string& mangled_name)
692{
693 return ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
694}
695
696//______________________________________________________________________________
697//
698//
699//
700
701int TCling_GenerateDictionary(const std::vector<std::string> &classes,
702 const std::vector<std::string> &headers,
703 const std::vector<std::string> &fwdDecls,
704 const std::vector<std::string> &unknown)
705{
706 //This function automatically creates the "LinkDef.h" file for templated
707 //classes then executes CompileMacro on it.
708 //The name of the file depends on the class name, and it's not generated again
709 //if the file exist.
710 if (classes.empty()) {
711 return 0;
712 }
713 // Use the name of the first class as the main name.
714 const std::string& className = classes[0];
715 //(0) prepare file name
716 TString fileName = "AutoDict_";
717 std::string::const_iterator sIt;
718 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
719 if (*sIt == '<' || *sIt == '>' ||
720 *sIt == ' ' || *sIt == '*' ||
721 *sIt == ',' || *sIt == '&' ||
722 *sIt == ':') {
723 fileName += '_';
724 }
725 else {
726 fileName += *sIt;
727 }
728 }
729 if (classes.size() > 1) {
730 Int_t chk = 0;
731 std::vector<std::string>::const_iterator it = classes.begin();
732 while ((++it) != classes.end()) {
733 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
734 chk = chk * 3 + it->at(cursor);
735 }
736 }
737 fileName += TString::Format("_%u", chk);
738 }
739 fileName += ".cxx";
740 if (gSystem->AccessPathName(fileName) != 0) {
741 //file does not exist
742 //(1) prepare file data
743 // If STL, also request iterators' operators.
744 // vector is special: we need to check whether
745 // vector::iterator is a typedef to pointer or a
746 // class.
747 static const std::set<std::string> sSTLTypes {
748 "vector","list","forward_list","deque","map","unordered_map","multimap",
749 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
750 "queue","priority_queue","stack","iterator"};
751 std::vector<std::string>::const_iterator it;
752 std::string fileContent("");
753 for (it = headers.begin(); it != headers.end(); ++it) {
754 fileContent += "#include \"" + *it + "\"\n";
755 }
756 for (it = unknown.begin(); it != unknown.end(); ++it) {
757 TClass* cl = TClass::GetClass(it->c_str());
758 if (cl && cl->GetDeclFileName()) {
759 TString header(gSystem->BaseName(cl->GetDeclFileName()));
761 TString dirbase(gSystem->BaseName(dir));
762 while (dirbase.Length() && dirbase != "."
763 && dirbase != "include" && dirbase != "inc"
764 && dirbase != "prec_stl") {
765 gSystem->PrependPathName(dirbase, header);
766 dir = gSystem->DirName(dir);
767 }
768 fileContent += TString("#include \"") + header + "\"\n";
769 }
770 }
771 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
772 fileContent += "class " + *it + ";\n";
773 }
774 fileContent += "#ifdef __CINT__ \n";
775 fileContent += "#pragma link C++ nestedclasses;\n";
776 fileContent += "#pragma link C++ nestedtypedefs;\n";
777 for (it = classes.begin(); it != classes.end(); ++it) {
778 std::string n(*it);
779 size_t posTemplate = n.find('<');
780 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
781 if (posTemplate != std::string::npos) {
782 n.erase(posTemplate, std::string::npos);
783 if (n.compare(0, 5, "std::") == 0) {
784 n.erase(0, 5);
785 }
786 iSTLType = sSTLTypes.find(n);
787 }
788 fileContent += "#pragma link C++ class ";
789 fileContent += *it + "+;\n" ;
790 fileContent += "#pragma link C++ class ";
791 if (iSTLType != sSTLTypes.end()) {
792 // STL class; we cannot (and don't need to) store iterators;
793 // their shadow and the compiler's version don't agree. So
794 // don't ask for the '+'
795 fileContent += *it + "::*;\n" ;
796 }
797 else {
798 // Not an STL class; we need to allow the I/O of contained
799 // classes (now that we have a dictionary for them).
800 fileContent += *it + "::*+;\n" ;
801 }
802 }
803 fileContent += "#endif\n";
804 //end(1)
805 //(2) prepare the file
806 FILE* filePointer;
807 filePointer = fopen(fileName, "w");
808 if (filePointer == NULL) {
809 //can't open a file
810 return 1;
811 }
812 //end(2)
813 //write data into the file
814 fprintf(filePointer, "%s", fileContent.c_str());
815 fclose(filePointer);
816 }
817 //(3) checking if we can compile a macro, if not then cleaning
818 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
819 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
820 Int_t ret = gSystem->CompileMacro(fileName, "k");
821 gErrorIgnoreLevel = oldErrorIgnoreLevel;
822 if (ret == 0) { //can't compile a macro
823 return 2;
824 }
825 //end(3)
826 return 0;
827}
828
829int TCling_GenerateDictionary(const std::string& className,
830 const std::vector<std::string> &headers,
831 const std::vector<std::string> &fwdDecls,
832 const std::vector<std::string> &unknown)
833{
834 //This function automatically creates the "LinkDef.h" file for templated
835 //classes then executes CompileMacro on it.
836 //The name of the file depends on the class name, and it's not generated again
837 //if the file exist.
838 std::vector<std::string> classes;
839 classes.push_back(className);
840 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
841}
842
843//______________________________________________________________________________
844//
845//
846//
847
848// It is a "fantom" method to synchronize user keyboard input
849// and ROOT prompt line (for WIN32)
850const char* fantomline = "TRint::EndOfLineAction();";
851
852//______________________________________________________________________________
853//
854//
855//
856
858
859//______________________________________________________________________________
860//
861// llvm error handler through exceptions; see also cling/UserInterface
862//
863namespace {
864 // Handle fatal llvm errors by throwing an exception.
865 // Yes, throwing exceptions in error handlers is bad.
866 // Doing nothing is pretty terrible, too.
867 void exceptionErrorHandler(void * /*user_data*/,
868 const std::string& reason,
869 bool /*gen_crash_diag*/) {
870 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
871 }
872}
873
874//______________________________________________________________________________
875//
876//
877//
878
879////////////////////////////////////////////////////////////////////////////////
880
881namespace{
882 // An instance of this class causes the diagnostics of clang to be suppressed
883 // during its lifetime
884 class clangDiagSuppr {
885 public:
886 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
887 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
888 fDiagEngine.setIgnoreAllWarnings(true);
889 }
890
891 ~clangDiagSuppr() {
892 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
893 }
894 private:
895 clang::DiagnosticsEngine& fDiagEngine;
896 bool fOldDiagValue;
897 };
898
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Allow calling autoparsing from TMetaUtils
903bool TClingLookupHelper__AutoParse(const char *cname)
904{
905 return gCling->AutoParse(cname);
906}
907
908////////////////////////////////////////////////////////////////////////////////
909/// Try hard to avoid looking up in the Cling database as this could enduce
910/// an unwanted autoparsing.
911
912bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
913 std::string &result)
914{
915 result.clear();
916
917 unsigned long offset = 0;
918 if (strncmp(tname.c_str(), "const ", 6) == 0) {
919 offset = 6;
920 }
921 unsigned long end = tname.length();
922 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
923 if ( tname[end-1]==']' ) {
924 --end;
925 while ( end && tname[end-1]!='[' ) --end;
926 }
927 --end;
928 }
929 std::string innerbuf;
930 const char *inner;
931 if (end != tname.length()) {
932 innerbuf = tname.substr(offset,end-offset);
933 inner = innerbuf.c_str();
934 } else {
935 inner = tname.c_str()+offset;
936 }
937
938 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
939 if (gROOT->GetListOfClasses()->FindObject(inner)
940 || TClassTable::Check(inner,result) ) {
941 // This is a known class.
942 return true;
943 }
944
945 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
946 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
947 if (type) {
948 // This is a raw type and an already loaded typedef.
949 const char *newname = type->GetFullTypeName();
950 if (type->GetType() == kLong64_t) {
951 newname = "Long64_t";
952 } else if (type->GetType() == kULong64_t) {
953 newname = "ULong64_t";
954 }
955 if (strcmp(inner,newname) == 0) {
956 return true;
957 }
958 if (offset) result = "const ";
959 result += newname;
960 if ( end != tname.length() ) {
961 result += tname.substr(end,tname.length()-end);
962 }
963 if (result == tname) result.clear();
964 return true;
965 }
966
967 // Check if the name is an enumerator
968 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
969 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
970 {
971 // We have a scope
972 // All of this C gymnastic is to avoid allocations on the heap
973 const auto enName = lastPos;
974 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
975 char *scopeName = new char[scopeNameSize + 1];
976 strncpy(scopeName, inner, scopeNameSize);
977 scopeName[scopeNameSize] = '\0';
978 // Check if the scope is in the list of classes
979 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
980 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
981 if (enumTable && enumTable->THashList::FindObject(enName)) return true;
982 }
983 // It may still be in one of the loaded protoclasses
984 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
985 auto listOfEnums = scope->GetListOfEnums();
986 if (listOfEnums) { // it could be null: no enumerators in the protoclass
987 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
988 if (enumTable && enumTable->THashList::FindObject(enName)) return true;
989 }
990 }
991 delete [] scopeName;
992 } else
993 {
994 // We don't have any scope: this could only be a global enum
995 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
996 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
997 }
998
999 if (gCling->GetClassSharedLibs(inner))
1000 {
1001 // This is a class name.
1002 return true;
1003 }
1004
1005 return false;
1006}
1007
1008////////////////////////////////////////////////////////////////////////////////
1009
1011{
1012 fContent.reserve(size);
1013}
1014
1015////////////////////////////////////////////////////////////////////////////////
1016
1018{
1019 return fContent.c_str();
1020}
1021
1022////////////////////////////////////////////////////////////////////////////////
1023/// Append string to the storage if not added already.
1024
1025inline bool TCling::TUniqueString::Append(const std::string& str)
1026{
1027 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1028 if (notPresent){
1029 fContent+=str;
1030 }
1031 return notPresent;
1032}
1033
1034std::string TCling::ToString(const char* type, void* obj)
1035{
1036 return fInterpreter->toString(type, obj);
1037}
1038
1039////////////////////////////////////////////////////////////////////////////////
1040///\returns true if the module map was loaded, false on error or if the map was
1041/// already loaded.
1042static bool RegisterPrebuiltModulePath(clang::Preprocessor& PP,
1043 const std::string& FullPath) {
1044 assert(llvm::sys::path::is_absolute(FullPath));
1045 FileManager& FM = PP.getFileManager();
1046 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1047 // We should look for modulemap files there too.
1048 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1049 if (DE) {
1050 HeaderSearch& HS = PP.getHeaderSearchInfo();
1051 const FileEntry *FE = HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1052 // FIXME: Calling IsLoaded is slow! Replace this with the appropriate
1053 // call to the clang::ModuleMap class.
1054 if (FE && !gCling->IsLoaded(FE->getName().data())) {
1055 if (!HS.loadModuleMapFile(FE, /*IsSystem*/ false)) {
1056 // We have loaded successfully the modulemap. Add the path to the
1057 // prebuilt module paths.
1058 HS.getHeaderSearchOpts().AddPrebuiltModulePath(FullPath);
1059 return true;
1060 }
1061 Error("TCling::LoadModule", "Could not load modulemap in the current directory");
1062 }
1063 }
1064 return false;
1065}
1066
1067////////////////////////////////////////////////////////////////////////////////
1068///\returns true if the module was loaded.
1069static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp, bool Complain = true)
1070{
1071 // When starting up ROOT, cling would load all modulemap files on the include
1072 // paths. However, in a ROOT session, it is very common to run aclic which
1073 // will invoke rootcling and possibly produce a modulemap and a module in
1074 // the current folder.
1075 //
1076 // Before failing, try loading the modulemap in the current folder and try
1077 // loading the requested module from it.
1078 clang::Preprocessor& PP = interp.getCI()->getPreprocessor();
1079 std::string currentDir = gSystem->WorkingDirectory();
1080 assert(!currentDir.empty());
1081 RegisterPrebuiltModulePath(PP, currentDir);
1082 return interp.loadModule(ModuleName, Complain);
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Loads the C++ modules that we require to run any ROOT program. This is just
1087/// supposed to make a C++ module from a modulemap available to the interpreter.
1088static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1089{
1090 for (const auto &modName : modules)
1091 LoadModule(modName, interp);
1092}
1093
1094static bool IsFromRootCling() {
1095 // rootcling also uses TCling for generating the dictionary ROOT files.
1096 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1097 return foundSymbol;
1098}
1099
1100static std::string GetModuleNameAsString(clang::Module *M, const clang::Preprocessor &PP)
1101{
1102 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1103
1104 std::string ModuleFileName;
1105 if (!HSOpts.PrebuiltModulePaths.empty())
1106 // Load the module from *only* in the prebuilt module path.
1107 ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(M->Name, /*ModuleMapPath*/"", /*UsePrebuiltPath*/ true);
1108 if (ModuleFileName.empty()) return "";
1109
1110 std::string ModuleName = llvm::sys::path::filename(ModuleFileName);
1111 // Return stem of the filename
1112 return std::string(llvm::sys::path::stem(ModuleName));
1113}
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Initialize the cling interpreter interface.
1117/// \param argv - array of arguments passed to the cling::Interpreter constructor
1118/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1119
1120TCling::TCling(const char *name, const char *title, const char* const argv[])
1125{
1126 const bool fromRootCling = IsFromRootCling();
1127
1128 fCxxModulesEnabled = false;
1129#ifdef R__USE_CXXMODULES
1130 fCxxModulesEnabled = true;
1131#endif
1132
1133 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1134
1135 fTemporaries = new std::vector<cling::Value>();
1136
1137 std::vector<std::string> clingArgsStorage;
1138 clingArgsStorage.push_back("cling4root");
1139 for (const char* const* arg = argv; *arg; ++arg)
1140 clingArgsStorage.push_back(*arg);
1141
1142 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1143 if (!fromRootCling) {
1144 ROOT::TMetaUtils::SetPathsForRelocatability(clingArgsStorage);
1145
1146 // Add -I early so ASTReader can find the headers.
1147 std::string interpInclude(TROOT::GetEtcDir().Data());
1148 clingArgsStorage.push_back("-I" + interpInclude);
1149
1150 // Add include path to etc/cling.
1151 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1152
1153 // Add the root include directory and etc/ to list searched by default.
1154 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1155
1156 // Add the current path to the include path
1157 // TCling::AddIncludePath(".");
1158
1159 // Attach the PCH (unless we have C++ modules enabled which provide the
1160 // same functionality).
1161 if (!fCxxModulesEnabled) {
1162 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1163 if (gSystem->Getenv("ROOT_PCH")) {
1164 pchFilename = gSystem->Getenv("ROOT_PCH");
1165 }
1166
1167 clingArgsStorage.push_back("-include-pch");
1168 clingArgsStorage.push_back(pchFilename);
1169 }
1170
1171 clingArgsStorage.push_back("-Wno-undefined-inline");
1172 clingArgsStorage.push_back("-fsigned-char");
1173 }
1174
1175 // Process externally passed arguments if present.
1176 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1177 if (EnvOpt.hasValue()) {
1178 StringRef Env(*EnvOpt);
1179 while (!Env.empty()) {
1180 StringRef Arg;
1181 std::tie(Arg, Env) = Env.split(' ');
1182 clingArgsStorage.push_back(Arg.str());
1183 }
1184 }
1185
1186 // FIXME: This only will enable frontend timing reports.
1187 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1188 if (EnvOpt.hasValue())
1189 clingArgsStorage.push_back("-ftime-report");
1190
1191 // Add the overlay file. Note that we cannot factor it out for both root
1192 // and rootcling because rootcling activates modules only if -cxxmodule
1193 // flag is passed.
1194 if (fCxxModulesEnabled && !fromRootCling)
1195 clingArgsStorage.push_back("-modulemap_overlay=" + std::string(TROOT::GetIncludeDir().Data()));
1196
1197 std::vector<const char*> interpArgs;
1198 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1199 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1200 interpArgs.push_back(iArg->c_str());
1201
1202 // Activate C++ modules support. If we are running within rootcling, it's up
1203 // to rootcling to set this flag depending on whether it wants to produce
1204 // C++ modules.
1205 TString vfsArg;
1206 if (fCxxModulesEnabled && !fromRootCling) {
1207 // We only set this flag, rest is done by the CIFactory.
1208 interpArgs.push_back("-fmodules");
1209 // We should never build modules during runtime, so let's enable the
1210 // module build remarks from clang to make it easier to spot when we do
1211 // this by accident.
1212 interpArgs.push_back("-Rmodule-build");
1213 }
1214
1215#ifdef R__FAST_MATH
1216 // Same setting as in rootcling_impl.cxx.
1217 interpArgs.push_back("-ffast-math");
1218#endif
1219
1220#ifdef R__EXTERN_LLVMDIR
1221 TString llvmResourceDir = R__EXTERN_LLVMDIR;
1222#else
1223 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1224#endif
1225 // Add statically injected extra arguments, usually coming from rootcling.
1226 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1227 extraArgs && *extraArgs; ++extraArgs) {
1228 if (!strcmp(*extraArgs, "-resource-dir")) {
1229 // Take the next arg as the llvm resource directory.
1230 llvmResourceDir = *(++extraArgs);
1231 } else {
1232 interpArgs.push_back(*extraArgs);
1233 }
1234 }
1235
1236 for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1237 interpArgs.push_back(arg.c_str());
1238 }
1239
1240 fInterpreter = new cling::Interpreter(interpArgs.size(),
1241 &(interpArgs[0]),
1242 llvmResourceDir);
1243
1244 if (!fromRootCling) {
1245 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1246 }
1247
1248 // Don't check whether modules' files exist.
1249 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
1250
1251 // Until we can disable autoloading during Sema::CorrectTypo() we have
1252 // to disable spell checking.
1253 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1254
1255
1256 // We need stream that doesn't close its file descriptor, thus we are not
1257 // using llvm::outs. Keeping file descriptor open we will be able to use
1258 // the results in pipes (Savannah #99234).
1259 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1260 fMetaProcessor = new cling::MetaProcessor(*fInterpreter, fMPOuts);
1261
1262 if (fInterpreter->getCI()->getLangOpts().Modules) {
1263 // Setup core C++ modules if we have any to setup.
1264
1265 // Load libc and stl first.
1266#ifdef R__MACOSX
1267 LoadModules({"Darwin", "std"}, *fInterpreter);
1268#else
1269 LoadModules({"libc", "stl"}, *fInterpreter);
1270#endif
1271
1272 // Load core modules
1273 // This should be vector in order to be able to pass it to LoadModules
1274 std::vector<std::string> CoreModules = {"ROOT_Foundation_C","ROOT_Config",
1275 "ROOT_Foundation_Stage1_NoRTTI", "Core", "RIO"};
1276
1277 // FIXME: Reducing those will let us be less dependent on rootmap files
1278 static constexpr std::array<const char*, 3> ExcludeModules =
1279 { { "Rtools", "RSQLite", "RInterface"} };
1280
1281 LoadModules(CoreModules, *fInterpreter);
1282
1283 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1284 if (!fromRootCling) {
1285 // Dynamically get all the modules and load them if they are not in core modules
1286 clang::CompilerInstance &CI = *fInterpreter->getCI();
1287 clang::ModuleMap &moduleMap = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap();
1288 clang::Preprocessor &PP = CI.getPreprocessor();
1289 std::vector<std::string> ModulesPreloaded;
1290
1291 for (auto I = moduleMap.module_begin(), E = moduleMap.module_end(); I != E; ++I) {
1292 clang::Module *M = I->second;
1293 assert(M);
1294
1295 std::string ModuleName = GetModuleNameAsString(M, PP);
1296 if (!ModuleName.empty() &&
1297 std::find(CoreModules.begin(), CoreModules.end(), ModuleName) == CoreModules.end()
1298 && std::find(ExcludeModules.begin(), ExcludeModules.end(), ModuleName) == ExcludeModules.end()) {
1299 if (M->IsSystem && !M->IsMissingRequirement)
1300 LoadModule(ModuleName, *fInterpreter);
1301 else if (!M->IsSystem && !M->IsMissingRequirement)
1302 ModulesPreloaded.push_back(ModuleName);
1303 }
1304 }
1305 LoadModules(ModulesPreloaded, *fInterpreter);
1306 }
1307
1308 // Check that the gROOT macro was exported by any core module.
1309 assert(fInterpreter->getMacro("gROOT") && "Couldn't load gROOT macro?");
1310
1311 // C99 decided that it's a very good idea to name a macro `I` (the letter I).
1312 // This seems to screw up nearly all the template code out there as `I` is
1313 // common template parameter name and iterator variable name.
1314 // Let's follow the GCC recommendation and undefine `I` in case any of the
1315 // core modules have defined it:
1316 // https://www.gnu.org/software/libc/manual/html_node/Complex-Numbers.html
1317 fInterpreter->declare("#ifdef I\n #undef I\n #endif\n");
1318
1319 // These macros are from loading R related modules, which conflict with
1320 // user's code.
1321 fInterpreter->declare("#ifdef PI\n #undef PI\n #endif\n");
1322 fInterpreter->declare("#ifdef ERROR\n #undef ERROR\n #endif\n");
1323 }
1324
1325 // For the list to also include string, we have to include it now.
1326 // rootcling does parts already if needed, e.g. genreflex does not want using
1327 // namespace std.
1328 if (fromRootCling) {
1329 fInterpreter->declare("#include \"RtypesCore.h\"\n"
1330 "#include <string>\n"
1331 "using std::string;\n"
1332 "#include <cassert>\n");
1333 } else {
1334 fInterpreter->declare("#include \"Rtypes.h\"\n"
1335 + gClassDefInterpMacro + "\n"
1336 + gInterpreterClassDef + "\n"
1337 "#undef ClassImp\n"
1338 "#define ClassImp(X);\n"
1339 "#include <string>\n"
1340 "using namespace std;\n"
1341 "#include <cassert>\n");
1342 }
1343
1344 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1345 fNormalizedCtxt = new ROOT::TMetaUtils::TNormalizedCtxt(fInterpreter->getLookupHelper());
1346 fLookupHelper = new ROOT::TMetaUtils::TClingLookupHelper(*fInterpreter, *fNormalizedCtxt,
1351
1352 // Initialize the cling interpreter interface.
1353 fMore = 0;
1354 fPrompt[0] = 0;
1355 fMapfile = 0;
1356// fMapNamespaces = 0;
1357 fRootmapFiles = 0;
1359
1360 fAllowLibLoad = !fromRootCling;
1361 // Disallow auto-parsing in rootcling
1362 fIsAutoParsingSuspended = fromRootCling;
1363 // Disable the autoloader until it is explicitly enabled.
1364 SetClassAutoloading(false);
1365
1366 ResetAll();
1367#ifndef R__WIN32
1368 //optind = 1; // make sure getopt() works in the main program
1369#endif // R__WIN32
1370
1371 // Enable dynamic lookup
1372 if (!fromRootCling) {
1373 fInterpreter->enableDynamicLookup();
1374 }
1375
1376 // Attach cling callbacks last; they might need TROOT::fInterpreter
1377 // and should thus not be triggered during the equivalent of
1378 // TROOT::fInterpreter = new TCling;
1379 std::unique_ptr<TClingCallbacks>
1380 clingCallbacks(new TClingCallbacks(fInterpreter));
1381 fClingCallbacks = clingCallbacks.get();
1383 fInterpreter->setCallbacks(std::move(clingCallbacks));
1384
1385}
1386
1387
1388////////////////////////////////////////////////////////////////////////////////
1389/// Destroy the interpreter interface.
1390
1392{
1393 fIsShuttingDown = true;
1394 delete fMapfile;
1395// delete fMapNamespaces;
1396 delete fRootmapFiles;
1397 delete fMetaProcessor;
1398 delete fTemporaries;
1399 delete fNormalizedCtxt;
1400 delete fInterpreter;
1401 delete fLookupHelper;
1402 gCling = 0;
1403#if defined(R__MUST_REVISIT)
1404#if R__MUST_REVISIT(6,2)
1405 Warning("~TCling", "Interface not available yet.");
1406#ifdef R__COMPLETE_MEM_TERMINATION
1407 // remove all cling objects
1408#endif
1409#endif
1410#endif
1411 //--
1412}
1413
1414////////////////////////////////////////////////////////////////////////////////
1415/// Initialize the interpreter, once TROOT::fInterpreter is set.
1416
1418{
1420}
1421
1423{
1424 fIsShuttingDown = true;
1425 ResetGlobals();
1426}
1427
1428////////////////////////////////////////////////////////////////////////////////
1429/// Wrapper around dladdr (and friends)
1430
1431static std::string FindLibraryName(void (*func)())
1432{
1433#if defined(__CYGWIN__) && defined(__GNUC__)
1434 return {};
1435#elif defined(G__WIN32)
1436 MEMORY_BASIC_INFORMATION mbi;
1437 if (!VirtualQuery (func, &mbi, sizeof (mbi)))
1438 {
1439 return {};
1440 }
1441
1442 HMODULE hMod = (HMODULE) mbi.AllocationBase;
1443 char moduleName[MAX_PATH];
1444
1445 if (!GetModuleFileNameA (hMod, moduleName, sizeof (moduleName)))
1446 {
1447 return {};
1448 }
1449 return moduleName;
1450#else
1451 Dl_info info;
1452 if (dladdr((void*)func, &info) == 0) {
1453 // Not in a known shared library, let's give up
1454 return {};
1455 } else {
1456 if (strchr(info.dli_fname, '/'))
1457 return info.dli_fname;
1458 // Else absolute path. For all we know that's a binary.
1459 // Some people have dictionaries in binaries, this is how we find their path:
1460 // (see also https://stackoverflow.com/a/1024937/6182509)
1461# if defined(R__MACOSX)
1462 char buf[PATH_MAX] = { 0 };
1463 uint32_t bufsize = sizeof(buf);
1464 if (_NSGetExecutablePath(buf, &bufsize) >= 0)
1465 return buf;
1466 return info.dli_fname;
1467# elif defined(R__UNIX)
1468 char buf[PATH_MAX] = { 0 };
1469 // Cross our fingers that /proc/self/exe exists.
1470 if (readlink("/proc/self/exe", buf, sizeof(buf)) > 0)
1471 return buf;
1472 std::string pipeCmd = std::string("which \"") + info.dli_fname + "\"";
1473 FILE* pipe = popen(pipeCmd.c_str(), "r");
1474 if (!pipe)
1475 return info.dli_fname;
1476 std::string result;
1477 while (fgets(buf, sizeof(buf), pipe)) {
1478 result += buf;
1479 }
1480 pclose(pipe);
1481 return result;
1482# else
1483# error "Unsupported platform."
1484# endif
1485 return {};
1486 }
1487#endif
1488
1489}
1490
1491////////////////////////////////////////////////////////////////////////////////
1492/// Helper to initialize TVirtualStreamerInfo's factor early.
1493/// Use static initialization to insure only one TStreamerInfo is created.
1495{
1496 // Use lambda since SetFactory return void.
1497 auto setFactory = []() {
1499 return kTRUE;
1500 };
1501 static bool doneFactory = setFactory();
1502 return doneFactory; // avoid unused variable warning.
1503}
1504
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Tries to load a PCM; returns true on success.
1508
1509bool TCling::LoadPCM(const std::string &pcmFileNameFullPath)
1510{
1511
1512 SuspendAutoloadingRAII autoloadOff(this);
1513 SuspendAutoParsing autoparseOff(this);
1514 assert(!pcmFileNameFullPath.empty());
1515 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1516 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1517 return false;
1518 }
1519
1520 // Easier to work with the ROOT interfaces.
1521 TString pcmFileName = pcmFileNameFullPath;
1522
1523 // Prevent the ROOT-PCMs hitting this during auto-load during
1524 // JITting - which will cause recursive compilation.
1525 // Avoid to call the plugin manager at all.
1527
1528 if (gROOT->IsRootFile(pcmFileName)) {
1529 Int_t oldDebug = gDebug;
1530 if (gDebug > 5) {
1531 gDebug -= 5;
1532 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1533 } else {
1534 gDebug = 0;
1535 }
1536
1538
1539 TFile *pcmFile = new TFile(pcmFileName+"?filetype=pcm","READ");
1540
1541 auto listOfKeys = pcmFile->GetListOfKeys();
1542
1543 // This is an empty pcm
1544 if (
1545 listOfKeys &&
1546 (
1547 (listOfKeys->GetSize() == 0) || // Nothing here, or
1548 (
1549 (listOfKeys->GetSize() == 1) && // only one, and
1550 !strcmp(((TKey*)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1551 )
1552 )
1553 ) {
1554 delete pcmFile;
1555 gDebug = oldDebug;
1556 return kTRUE;
1557 }
1558
1559 TObjArray *protoClasses;
1560 if (gDebug > 1)
1561 ::Info("TCling::LoadPCM","reading protoclasses for %s \n",pcmFileName.Data());
1562
1563 pcmFile->GetObject("__ProtoClasses", protoClasses);
1564
1565 if (protoClasses) {
1566 for (auto obj : *protoClasses) {
1567 TProtoClass * proto = (TProtoClass*)obj;
1569 }
1570 // Now that all TClass-es know how to set them up we can update
1571 // existing TClasses, which might cause the creation of e.g. TBaseClass
1572 // objects which in turn requires the creation of TClasses, that could
1573 // come from the PCH, but maybe later in the loop. Instead of resolving
1574 // a dependency graph the addition to the TClassTable above allows us
1575 // to create these dependent TClasses as needed below.
1576 for (auto proto : *protoClasses) {
1577 if (TClass* existingCl
1578 = (TClass*)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1579 // We have an existing TClass object. It might be emulated
1580 // or interpreted; we now have more information available.
1581 // Make that available.
1582 if (existingCl->GetState() != TClass::kHasTClassInit) {
1583 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1584 if (!dict) {
1585 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s",
1586 proto->GetName());
1587 } else {
1588 // This will replace the existing TClass.
1589 TClass *ncl = (*dict)();
1590 if (ncl) ncl->PostLoadCheck();
1591
1592 }
1593 }
1594 }
1595 }
1596
1597 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1598 delete protoClasses;
1599 }
1600
1601 TObjArray *dataTypes;
1602 pcmFile->GetObject("__Typedefs", dataTypes);
1603 if (dataTypes) {
1604 for (auto typedf: *dataTypes)
1605 gROOT->GetListOfTypes()->Add(typedf);
1606 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1607 delete dataTypes;
1608 }
1609
1610 TObjArray *enums;
1611 pcmFile->GetObject("__Enums", enums);
1612 if (enums) {
1613 // Cache the pointers
1614 auto listOfGlobals = gROOT->GetListOfGlobals();
1615 auto listOfEnums = dynamic_cast<THashList*>(gROOT->GetListOfEnums());
1616 // Loop on enums and then on enum constants
1617 for (auto selEnum: *enums){
1618 const char* enumScope = selEnum->GetTitle();
1619 const char* enumName = selEnum->GetName();
1620 if (strcmp(enumScope,"") == 0){
1621 // This is a global enum and is added to the
1622 // list of enums and its constants to the list of globals
1623 if (!listOfEnums->THashList::FindObject(enumName)){
1624 ((TEnum*) selEnum)->SetClass(nullptr);
1625 listOfEnums->Add(selEnum);
1626 }
1627 for (auto enumConstant: *static_cast<TEnum*>(selEnum)->GetConstants()){
1628 if (!listOfGlobals->FindObject(enumConstant)){
1629 listOfGlobals->Add(enumConstant);
1630 }
1631 }
1632 }
1633 else {
1634 // This enum is in a namespace. A TClass entry is bootstrapped if
1635 // none exists yet and the enum is added to it
1636 TClass* nsTClassEntry = TClass::GetClass(enumScope);
1637 if (!nsTClassEntry){
1638 nsTClassEntry = new TClass(enumScope,0,TClass::kNamespaceForMeta, true);
1639 }
1640 auto listOfEnums = nsTClassEntry->fEnums.load();
1641 if (!listOfEnums) {
1642 if ( (kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property() ) {
1643 // For this case, the list will be immutable once constructed
1644 // (i.e. in this case, by the end of this routine).
1645 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1646 } else {
1647 //namespaces can have enums added to them
1648 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1649 }
1650 }
1651 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)){
1652 ((TEnum*) selEnum)->SetClass(nsTClassEntry);
1653 listOfEnums->Add(selEnum);
1654 }
1655 }
1656 }
1657 enums->Clear();
1658 delete enums;
1659 }
1660
1661 delete pcmFile;
1662
1663 gDebug = oldDebug;
1664 } else {
1665 if (gDebug > 5)
1666 ::Info("TCling::LoadPCM", "Loading clang PCM %s", pcmFileName.Data());
1667
1668 }
1669 return kTRUE;
1670}
1671
1672//______________________________________________________________________________
1673
1674namespace {
1675 using namespace clang;
1676
1677 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1678 // This class is to be considered an helper for autoparsing.
1679 // It visits the AST and marks all classes (in all of their redeclarations)
1680 // with the setHasExternalLexicalStorage method.
1681 public:
1682 bool VisitRecordDecl(clang::RecordDecl* rcd){
1683 if (gDebug > 2)
1684 Info("ExtLexicalStorageAdder",
1685 "Adding external lexical storage to class %s",
1686 rcd->getNameAsString().c_str());
1687 auto reDeclPtr = rcd->getMostRecentDecl();
1688 do {
1689 reDeclPtr->setHasExternalLexicalStorage();
1690 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1691
1692 return false;
1693 }
1694 };
1695
1696
1697}
1698
1699////////////////////////////////////////////////////////////////////////////////
1700/// List of dicts that have the PCM information already in the PCH.
1701static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1702 "libRint",
1703 "libThread",
1704 "libRIO",
1705 "libImt",
1706 "libcomplexDict",
1707 "libdequeDict",
1708 "liblistDict",
1709 "libforward_listDict",
1710 "libvectorDict",
1711 "libmapDict",
1712 "libmultimap2Dict",
1713 "libmap2Dict",
1714 "libmultimapDict",
1715 "libsetDict",
1716 "libmultisetDict",
1717 "libunordered_setDict",
1718 "libunordered_multisetDict",
1719 "libunordered_mapDict",
1720 "libunordered_multimapDict",
1721 "libvalarrayDict",
1722 "G__GenVector32",
1723 "G__Smatrix32"};
1724
1725////////////////////////////////////////////////////////////////////////////////
1726/// Inject the module named "modulename" into cling; load all headers.
1727/// headers is a 0-terminated array of header files to #include after
1728/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
1729/// entries (or %PATH% on Windows).
1730/// This function gets called by the static initialization of dictionary
1731/// libraries.
1732/// The payload code is injected "as is" in the interpreter.
1733/// The value of 'triggerFunc' is used to find the shared library location.
1734
1735void TCling::RegisterModule(const char* modulename,
1736 const char** headers,
1737 const char** includePaths,
1738 const char* payloadCode,
1739 const char* fwdDeclsCode,
1740 void (*triggerFunc)(),
1741 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
1742 const char** classesHeaders,
1743 Bool_t lateRegistration /*=false*/,
1744 Bool_t hasCxxModule /*=false*/)
1745{
1746 const bool fromRootCling = IsFromRootCling();
1747 // We need the dictionary initialization but we don't want to inject the
1748 // declarations into the interpreter, except for those we really need for
1749 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
1750 if (fromRootCling) return;
1751
1752 // When we cannot provide a module for the library we should enable header
1753 // parsing. This 'mixed' mode ensures gradual migration to modules.
1754 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
1755 fHeaderParsingOnDemand = !hasCxxModule;
1756
1757 // Treat Aclic Libs in a special way. Do not delay the parsing.
1758 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
1759 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
1760 if (hasHeaderParsingOnDemand && isACLiC) {
1761 if (gDebug>1)
1762 Info("TCling::RegisterModule",
1763 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
1764 hasHeaderParsingOnDemand = false;
1765 }
1766
1767
1768 // Make sure we relookup symbols that were search for before we loaded
1769 // their autoparse information. We could be more subtil and remove only
1770 // the failed one or only the one in this module, but for now this is
1771 // better than nothing.
1772 fLookedUpClasses.clear();
1773
1774 // Make sure we do not set off autoloading or autoparsing during the
1775 // module registration!
1776 SuspendAutoloadingRAII autoLoadOff(this);
1777
1778 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
1779 TCling::AddIncludePath(*inclPath);
1780 }
1781 cling::Transaction* T = 0;
1782 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
1783 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
1784 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
1785 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
1786 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
1787 assert(cling::Interpreter::kSuccess == compRes &&
1788 "A fwd declaration could not be compiled");
1789 if (compRes!=cling::Interpreter::kSuccess){
1790 Warning("TCling::RegisterModule",
1791 "Problems in declaring string '%s' were encountered.",
1792 fwdDecl.c_str()) ;
1793 continue;
1794 }
1795
1796 // Drill through namespaces recursively until the template is found
1797 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
1798 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
1799 }
1800
1801 }
1802
1803 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
1804 // This is used to give Sema the same view on ACLiC'ed files (which
1805 // are then #included through the dictionary) as rootcling had.
1806 TString code = gNonInterpreterClassDef;
1807 if (payloadCode)
1808 code += payloadCode;
1809
1810 std::string dyLibName = FindLibraryName(triggerFunc);
1811
1812 if (dyLibName.empty()) {
1813 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
1814 return;
1815 }
1816
1817 // The triggerFunc may not be in a shared object but in an executable.
1818 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
1819
1820 bool wasDlopened = false;
1821
1822 // If this call happens after dlopen has finished (i.e. late registration)
1823 // there is no need to dlopen the library recursively. See ROOT-8437 where
1824 // the dyLibName would correspond to the binary.
1825 if (!lateRegistration) {
1826
1827 if (isSharedLib) {
1828 // We need to open the dictionary shared library, to resolve symbols
1829 // requested by the JIT from it: as the library is currently being dlopen'ed,
1830 // its symbols are not yet reachable from the process.
1831 // Recursive dlopen seems to work just fine.
1832 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
1833 if (!dyLibHandle) {
1834#ifdef R__WIN32
1835 char dyLibError[1000];
1836 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1837 dyLibError, sizeof(dyLibError), NULL);
1838#else
1839 const char* dyLibError = dlerror();
1840 if (dyLibError)
1841#endif
1842 {
1843 if (gDebug > 0) {
1844 ::Info("TCling::RegisterModule",
1845 "Cannot open shared library %s for dictionary %s:\n %s",
1846 dyLibName.c_str(), modulename, dyLibError);
1847 }
1848 }
1849 } else {
1850 fRegisterModuleDyLibs.push_back(dyLibHandle);
1851 wasDlopened = true;
1852 } // if (!dyLibHandle) .. else
1853 } // if (dyLibName)
1854 } // if (!lateRegistration)
1855
1856 if (hasHeaderParsingOnDemand && fwdDeclsCode){
1857 // We now parse the forward declarations. All the classes are then modified
1858 // in order for them to have an external lexical storage.
1859 std::string fwdDeclsCodeLessEnums;
1860 {
1861 // Search for enum forward decls and only declare them if no
1862 // declaration exists yet.
1863 std::string fwdDeclsLine;
1864 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
1865 std::vector<std::string> scopes;
1866 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
1867 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
1868 // We check if the line contains a fwd declaration of an enum
1869 if (enumPos != std::string::npos) {
1870 // We clear the scopes which we may have carried from a previous iteration
1871 scopes.clear();
1872 // We check if the enum is not in a scope. If yes, save its name
1873 // and the names of the enclosing scopes.
1874 if (enumPos != 0) {
1875 // it's enclosed in namespaces. We need to understand what they are
1876 auto nsPos = fwdDeclsLine.find("namespace");
1877 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
1878 while (nsPos < enumPos && nsPos != std::string::npos) {
1879 // we have a namespace, let's put it in the collection of scopes
1880 const auto nsNameStart = nsPos + 10;
1881 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
1882 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
1883 scopes.push_back(nsName);
1884 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
1885 }
1886 }
1887 clang::DeclContext* DC = 0;
1888 for (auto &&aScope: scopes) {
1889 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
1890 if (!DC) {
1891 // No decl context means we have to fwd declare the enum.
1892 break;
1893 }
1894 }
1895 if (scopes.empty() || DC) {
1896 // We know the scope; let's look for the enum.
1897 size_t posEnumName = fwdDeclsLine.find("\"))) ", 32);
1898 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
1899 posEnumName += 5; // skip "\"))) "
1900 while (isspace(fwdDeclsLine[posEnumName]))
1901 ++posEnumName;
1902 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
1903 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
1904 while (isspace(fwdDeclsLine[posEnumNameEnd]))
1905 --posEnumNameEnd;
1906 // posEnumNameEnd now points to the last character of the name.
1907
1908 std::string enumName = fwdDeclsLine.substr(posEnumName,
1909 posEnumNameEnd - posEnumName + 1);
1910
1911 if (clang::NamedDecl* enumDecl
1912 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
1913 enumName.c_str(), DC)) {
1914 // We have an existing enum decl (forward or definition);
1915 // skip this.
1916 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
1917 (void)enumDecl;
1918 continue;
1919 }
1920 }
1921 }
1922
1923 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
1924 }
1925 }
1926
1927 if (fwdDeclsCodeLessEnums.size() != 0){ // Avoid the overhead if nothing is to be declared
1928 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
1929 assert(cling::Interpreter::kSuccess == compRes &&
1930 "The forward declarations could not be compiled");
1931 if (compRes!=cling::Interpreter::kSuccess){
1932 Warning("TCling::RegisterModule",
1933 "Problems in compiling forward declarations for module %s: '%s'",
1934 modulename, fwdDeclsCodeLessEnums.c_str()) ;
1935 }
1936 else if (T){
1937 // Loop over all decls in the transaction and go through them all
1938 // to mark them properly.
1939 // In order to do that, we first iterate over all the DelayedCallInfos
1940 // within the transaction. Then we loop over all Decls in the DeclGroupRef
1941 // contained in the DelayedCallInfos. For each decl, we traverse.
1942 ExtLexicalStorageAdder elsa;
1943 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
1944 cling::Transaction::DelayCallInfo& dci = *dciIt;
1945 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
1946 clang::Decl* declPtr = *dit;
1947 elsa.TraverseDecl(declPtr);
1948 }
1949 }
1950 }
1951 }
1952
1953 // Now we register all the headers necessary for the class
1954 // Typical format of the array:
1955 // {"A", "classes.h", "@",
1956 // "vector<A>", "vector", "@",
1957 // "myClass", payloadCode, "@",
1958 // nullptr};
1959
1960 std::string temp;
1961 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
1962 temp=*classesHeader;
1963
1964 size_t theTemplateHash = 0;
1965 bool addTemplate = false;
1966 size_t posTemplate = temp.find('<');
1967 if (posTemplate != std::string::npos) {
1968 // Add an entry for the template itself.
1969 std::string templateName = temp.substr(0, posTemplate);
1970 theTemplateHash = fStringHashFunction(templateName);
1971 addTemplate = true;
1972 }
1973 size_t theHash = fStringHashFunction(temp);
1974 classesHeader++;
1975 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
1976 // This is done in order to distinguish headers from files and from the payloadCode
1977 if (payloadCode == *classesHeader_inner ){
1978 fPayloads.insert(theHash);
1979 if (addTemplate) fPayloads.insert(theTemplateHash);
1980 }
1981 if (gDebug > 2)
1982 Info("TCling::RegisterModule",
1983 "Adding a header for %s", temp.c_str());
1984 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
1985 if (addTemplate) {
1986 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
1987 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
1988 }
1989 addTemplate = false;
1990 }
1991 }
1992 }
1993 }
1994
1995 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
1996 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
1997 // The path dyLibName might not be absolute. This can happen if dyLibName
1998 // is linked to an executable in the same folder.
1999 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2000 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2001 llvm::sys::path::append(pcmFileNameFullPath,
2002 ROOT::TMetaUtils::GetModuleFileName(modulename));
2003 if (!LoadPCM(pcmFileNameFullPath.str().str())) {
2004 ::Error("TCling::RegisterModule", "cannot find dictionary module %s",
2005 ROOT::TMetaUtils::GetModuleFileName(modulename).c_str());
2006 }
2007 }
2008
2009 clang::Sema &TheSema = fInterpreter->getSema();
2010
2011 bool ModuleWasSuccessfullyLoaded = false;
2012 if (hasCxxModule) {
2013 std::string ModuleName = modulename;
2014 if (llvm::StringRef(modulename).startswith("lib"))
2015 ModuleName = llvm::StringRef(modulename).substr(3).str();
2016
2017 // In case we are directly loading the library via gSystem->Load() without
2018 // specifying the relevant include paths we should try loading the
2019 // modulemap next to the library location.
2020 clang::Preprocessor &PP = TheSema.getPreprocessor();
2021 // Can be nullptr in case of libCore.
2022 if (!dyLibName.empty())
2023 RegisterPrebuiltModulePath(PP, llvm::sys::path::parent_path(dyLibName));
2024
2025 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2026 // modules such as GenVector32 because it needs to fall back to GenVector.
2027 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter, /*Complain=*/ !isACLiC);
2028 if (!ModuleWasSuccessfullyLoaded) {
2029 // Only report if we found the module in the modulemap.
2030 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2031 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2032 if (moduleMap.findModule(ModuleName))
2033 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2034 }
2035 }
2036
2037 { // scope within which diagnostics are de-activated
2038 // For now we disable diagnostics because we saw them already at
2039 // dictionary generation time. That won't be an issue with the PCMs.
2040
2041 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2042
2043#if defined(R__MUST_REVISIT)
2044#if R__MUST_REVISIT(6,2)
2045 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2046#endif
2047#endif
2048
2049 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2050 SuspendAutoParsing autoParseRaii(this);
2051
2052 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2053 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2054 if (isACLiC) {
2055 // Register an unload point.
2056 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2057 }
2058
2059 assert(cling::Interpreter::kSuccess == compRes &&
2060 "Payload code of a dictionary could not be parsed correctly.");
2061 if (compRes!=cling::Interpreter::kSuccess) {
2062 Warning("TCling::RegisterModule",
2063 "Problems declaring payload for module %s.", modulename) ;
2064 }
2065 }
2066 }
2067
2068 // Now that all the header have been registered/compiled, let's
2069 // make sure to 'reset' the TClass that have a class init in this module
2070 // but already had their type information available (using information/header
2071 // loaded from other modules or from class rules).
2072 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2073 // This code is likely to be superseded by the similar code in LoadPCM,
2074 // and have been disabled, (inadvertently or awkwardly) by
2075 // commit 7903f09f3beea69e82ffba29f59fb2d656a4fd54 (Refactor the routines used for header parsing on demand)
2076 // whereas it seems that a more semantically correct conditional would have
2077 // been 'if this module does not have a rootpcm'.
2078 // Note: this need to be review when the clang pcm are being installed.
2079 // #if defined(R__MUST_REVISIT)
2080 while (!fClassesToUpdate.empty()) {
2081 TClass *oldcl = fClassesToUpdate.back().first;
2082 if (oldcl->GetState() != TClass::kHasTClassInit) {
2083 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2084 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2085 fClassesToUpdate.pop_back();
2086 // Calling func could manipulate the list so, let maintain the list
2087 // then call the dictionary function.
2088 TClass *ncl = dict();
2089 if (ncl) ncl->PostLoadCheck();
2090 } else {
2091 fClassesToUpdate.pop_back();
2092 }
2093 }
2094 }
2095
2096 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2097 // __ROOTCLING__ might be pulled in through PCH
2098 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2099 "#undef __ROOTCLING__\n"
2100 + gInterpreterClassDef +
2101 "#endif");
2102 }
2103
2104 if (wasDlopened) {
2105 assert(isSharedLib);
2106 void* dyLibHandle = fRegisterModuleDyLibs.back();
2107 fRegisterModuleDyLibs.pop_back();
2108 dlclose(dyLibHandle);
2109 }
2110}
2111
2112////////////////////////////////////////////////////////////////////////////////
2113/// Register classes that already existed prior to their dictionary loading
2114/// and that already had a ClassInfo (and thus would not be refresh via
2115/// UpdateClassInfo.
2116
2118{
2119 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2120}
2121
2122////////////////////////////////////////////////////////////////////////////////
2123/// If the dictionary is loaded, we can remove the class from the list
2124/// (otherwise the class might be loaded twice).
2125
2127{
2128 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2129 iterator stop = fClassesToUpdate.end();
2130 for(iterator i = fClassesToUpdate.begin();
2131 i != stop;
2132 ++i)
2133 {
2134 if ( i->first == oldcl ) {
2135 fClassesToUpdate.erase(i);
2136 return;
2137 }
2138 }
2139}
2140
2141
2142////////////////////////////////////////////////////////////////////////////////
2143/// Let cling process a command line.
2144///
2145/// If the command is executed and the error is 0, then the return value
2146/// is the int value corresponding to the result of the executed command
2147/// (float and double return values will be truncated).
2148///
2149
2150// Method for handling the interpreter exceptions.
2151// the MetaProcessor is passing in as argument to teh function, because
2152// cling::Interpreter::CompilationResult is a nested class and it cannot be
2153// forward declared, thus this method cannot be a static member function
2154// of TCling.
2155
2156static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2157 const char* input_line,
2158 cling::Interpreter::CompilationResult& compRes,
2159 cling::Value* result)
2160{
2161 try {
2162 return metaProcessor->process(input_line, compRes, result);
2163 }
2164 catch (cling::InterpreterException& ex)
2165 {
2166 Error("HandleInterpreterException", "%s.\n%s", ex.what(), "Execution of your code was aborted.");
2167 ex.diagnose();
2168 compRes = cling::Interpreter::kFailure;
2169 }
2170 return 0;
2171}
2172
2173////////////////////////////////////////////////////////////////////////////////
2174
2175bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2176{
2177 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2178 ie->diagnose();
2179 return true;
2180 }
2181 return false;
2182}
2183
2184////////////////////////////////////////////////////////////////////////////////
2185
2186Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
2187{
2188 // Copy the passed line, it comes from a static buffer in TApplication
2189 // which can be reentered through the Cling evaluation routines,
2190 // which would overwrite the static buffer and we would forget what we
2191 // were doing.
2192 //
2193 TString sLine(line);
2194 if (strstr(line,fantomline)) {
2195 // End-Of-Line action
2196 // See the comment (copied from above):
2197 // It is a "fantom" method to synchronize user keyboard input
2198 // and ROOT prompt line (for WIN32)
2199 // and is implemented by
2200 if (gApplication) {
2201 if (gApplication->IsCmdThread()) {
2203 gROOT->SetLineIsProcessing();
2204
2206
2207 gROOT->SetLineHasBeenProcessed();
2208 }
2209 }
2210 return 0;
2211 }
2212
2214 gGlobalMutex->Lock();
2215 if (!gInterpreterMutex)
2218 }
2220 gROOT->SetLineIsProcessing();
2221
2222 struct InterpreterFlagsRAII {
2223 cling::Interpreter* fInterpreter;
2224 bool fWasDynamicLookupEnabled;
2225
2226 InterpreterFlagsRAII(cling::Interpreter* interp):
2227 fInterpreter(interp),
2228 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2229 {
2230 fInterpreter->enableDynamicLookup(true);
2231 }
2232 ~InterpreterFlagsRAII() {
2233 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2234 gROOT->SetLineHasBeenProcessed();
2235 }
2236 } interpreterFlagsRAII(fInterpreter);
2237
2238 // A non-zero returned value means the given line was
2239 // not a complete statement.
2240 int indent = 0;
2241 // This will hold the resulting value of the evaluation the given line.
2242 cling::Value result;
2243 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2244 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2245 !strncmp(sLine.Data(), ".X", 2)) {
2246 // If there was a trailing "+", then CINT compiled the code above,
2247 // and we will need to strip the "+" before passing the line to cling.
2248 TString mod_line(sLine);
2249 TString aclicMode;
2250 TString arguments;
2251 TString io;
2252 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2253 aclicMode, arguments, io);
2254 if (aclicMode.Length()) {
2255 // Remove the leading '+'
2256 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2257 aclicMode[0]='k'; // We always want to keep the .so around.
2258 if (aclicMode[1]=='+') {
2259 // We have a 2nd +
2260 aclicMode[1]='f'; // We want to force the recompilation.
2261 }
2262 if (!gSystem->CompileMacro(fname,aclicMode)) {
2263 // ACLiC failed.
2264 compRes = cling::Interpreter::kFailure;
2265 } else {
2266 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2267 // if execution was requested.
2268
2269 if (arguments.Length()==0) {
2270 arguments = "()";
2271 }
2272 // We need to remove the extension.
2273 Ssiz_t ext = fname.Last('.');
2274 if (ext != kNPOS) {
2275 fname.Remove(ext);
2276 }
2277 const char *function = gSystem->BaseName(fname);
2278 mod_line = function + arguments + io;
2279 indent = HandleInterpreterException(fMetaProcessor, mod_line, compRes, &result);
2280 }
2281 }
2282 } else {
2283 // not ACLiC
2284 size_t unnamedMacroOpenCurly;
2285 {
2286 std::string code;
2287 std::string codeline;
2288 std::ifstream in(fname);
2289 while (in) {
2290 std::getline(in, codeline);
2291 code += codeline + "\n";
2292 }
2293 unnamedMacroOpenCurly
2294 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2295 }
2296
2297 fCurExecutingMacros.push_back(fname);
2298 if (unnamedMacroOpenCurly != std::string::npos) {
2299 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2300 unnamedMacroOpenCurly);
2301 } else {
2302 // No DynLookup for .x, .L of named macros.
2303 fInterpreter->enableDynamicLookup(false);
2304 indent = HandleInterpreterException(fMetaProcessor, mod_line, compRes, &result);
2305 }
2306 fCurExecutingMacros.pop_back();
2307 }
2308 } // .L / .X / .x
2309 else {
2310 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2311 // explicitly ignore .autodict without having to support it
2312 // in cling.
2313
2314 // Turn off autoparsing if this is an include directive
2315 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2316 if (isInclusionDirective) {
2317 SuspendAutoParsing autoParseRaii(this);
2318 indent = HandleInterpreterException(fMetaProcessor, sLine, compRes, &result);
2319 } else {
2320 indent = HandleInterpreterException(fMetaProcessor, sLine, compRes, &result);
2321 }
2322 }
2323 }
2324 if (result.isValid())
2325 RegisterTemporary(result);
2326 if (indent) {
2327 if (error)
2328 *error = kProcessing;
2329 return 0;
2330 }
2331 if (error) {
2332 switch (compRes) {
2333 case cling::Interpreter::kSuccess: *error = kNoError; break;
2334 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2335 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2336 }
2337 }
2338 if (compRes == cling::Interpreter::kSuccess
2339 && result.isValid()
2340 && !result.isVoid())
2341 {
2342 return result.simplisticCastAs<long>();
2343 }
2344 return 0;
2345}
2346
2347////////////////////////////////////////////////////////////////////////////////
2348/// No-op; see TRint instead.
2349
2351{
2352}
2353
2354////////////////////////////////////////////////////////////////////////////////
2355/// Add the given path to the list of directories in which the interpreter
2356/// looks for include files. Only one path item can be specified at a
2357/// time, i.e. "path1:path2" is NOT supported.
2358
2359void TCling::AddIncludePath(const char *path)
2360{
2362 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2363 // gCling->AddIncludePath() does not! Work around that inconsistency:
2364 if (path[0] == '-' && path[1] == 'I')
2365 path += 2;
2366
2367 fInterpreter->AddIncludePath(path);
2368}
2369
2370////////////////////////////////////////////////////////////////////////////////
2371/// Visit all members over members, recursing over base classes.
2372
2373void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2374 const TClass* cl, Bool_t isTransient)
2375{
2379 }
2380
2381 if (!cl || cl->GetCollectionProxy()) {
2382 // We do not need to investigate the content of the STL
2383 // collection, they are opaque to us (and details are
2384 // uninteresting).
2385 return;
2386 }
2387
2388 static const TClassRef clRefString("std::string");
2389 if (clRefString == cl) {
2390 // We stream std::string without going through members..
2391 return;
2392 }
2393
2394 if (TClassEdit::IsStdArray(cl->GetName())) {
2395 // We treat std arrays as C arrays
2396 return;
2397 }
2398
2399 const char* cobj = (const char*) obj; // for ptr arithmetics
2400
2401 // Treat the case of std::complex in a special manner. We want to enforce
2402 // the layout of a stl implementation independent class, which is the
2403 // complex as implemented in ROOT5.
2404
2405 // A simple lambda to simplify the code
2406 auto inspInspect = [&] (ptrdiff_t offset){
2407 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2408 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2409 };
2410
2411 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2412 switch(complexType) {
2414 {
2415 break;
2416 }
2418 {
2419 inspInspect(sizeof(float));
2420 return;
2421 }
2423 {
2424 inspInspect(sizeof(double));
2425 return;
2426 }
2428 {
2429 inspInspect(sizeof(int));
2430 return;
2431 }
2433 {
2434 inspInspect(sizeof(long));
2435 return;
2436 }
2437 }
2438
2439 static clang::PrintingPolicy
2440 printPol(fInterpreter->getCI()->getLangOpts());
2441 if (printPol.Indentation) {
2442 // not yet initialized
2443 printPol.Indentation = 0;
2444 printPol.SuppressInitializers = true;
2445 }
2446
2447 const char* clname = cl->GetName();
2448 // Printf("Inspecting class %s\n", clname);
2449
2450 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2451 const clang::Decl *scopeDecl = 0;
2452 const clang::Type *recordType = 0;
2453
2454 if (cl->GetClassInfo()) {
2455 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2456 scopeDecl = clingCI->GetDecl();
2457 recordType = clingCI->GetType();
2458 } else {
2459 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2460 // Diags will complain about private classes:
2461 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2462 &recordType);
2463 }
2464 if (!scopeDecl) {
2465 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2466 return;
2467 }
2468 const clang::CXXRecordDecl* recordDecl
2469 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2470 if (!recordDecl) {
2471 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2472 return;
2473 }
2474
2475 {
2476 // Force possible deserializations first. We need to have no pending
2477 // Transaction when passing control flow to the inspector below (ROOT-7779).
2478 cling::Interpreter::PushTransactionRAII deserRAII(fInterpreter);
2479
2480 astContext.getASTRecordLayout(recordDecl);
2481
2482 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2483 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2484 }
2485
2486 const clang::ASTRecordLayout& recLayout
2487 = astContext.getASTRecordLayout(recordDecl);
2488
2489 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2490 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2491 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2492 // cl->GetName());
2493 // }
2494 if (cl->Size() != recLayout.getSize().getQuantity()) {
2495 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2496 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2497 }
2498
2499 unsigned iNField = 0;
2500 // iterate over fields
2501 // FieldDecls are non-static, else it would be a VarDecl.
2502 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2503 eField = recordDecl->field_end(); iField != eField;
2504 ++iField, ++iNField) {
2505
2506
2507 clang::QualType memberQT = iField->getType();
2508 if (recordType) {
2509 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2510 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2511 }
2512 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2513 if (memberQT.isNull()) {
2514 std::string memberName;
2515 llvm::raw_string_ostream stream(memberName);
2516 // Don't trigger fopen of the source file to count lines:
2517 printPol.AnonymousTagLocations = false;
2518 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2519 stream.flush();
2520 Error("InspectMembers",
2521 "Cannot retrieve QualType for member %s while inspecting class %s",
2522 memberName.c_str(), clname);
2523 continue; // skip member
2524 }
2525 const clang::Type* memType = memberQT.getTypePtr();
2526 if (!memType) {
2527 std::string memberName;
2528 llvm::raw_string_ostream stream(memberName);
2529 // Don't trigger fopen of the source file to count lines:
2530 printPol.AnonymousTagLocations = false;
2531 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2532 stream.flush();
2533 Error("InspectMembers",
2534 "Cannot retrieve Type for member %s while inspecting class %s",
2535 memberName.c_str(), clname);
2536 continue; // skip member
2537 }
2538
2539 const clang::Type* memNonPtrType = memType;
2540 Bool_t ispointer = false;
2541 if (memNonPtrType->isPointerType()) {
2542 ispointer = true;
2543 clang::QualType ptrQT
2544 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2545 if (recordType) {
2546 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2547 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2548 }
2549 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2550 if (ptrQT.isNull()) {
2551 std::string memberName;
2552 llvm::raw_string_ostream stream(memberName);
2553 // Don't trigger fopen of the source file to count lines:
2554 printPol.AnonymousTagLocations = false;
2555 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2556 stream.flush();
2557 Error("InspectMembers",
2558 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2559 memberName.c_str(), clname);
2560 continue; // skip member
2561 }
2562 memNonPtrType = ptrQT.getTypePtr();
2563 }
2564
2565 // assemble array size(s): "[12][4][]"
2566 llvm::SmallString<8> arraySize;
2567 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2568 unsigned arrLevel = 0;
2569 bool haveErrorDueToArray = false;
2570 while (arrType) {
2571 ++arrLevel;
2572 arraySize += '[';
2573 const clang::ConstantArrayType* constArrType =
2574 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2575 if (constArrType) {
2576 constArrType->getSize().toStringUnsigned(arraySize);
2577 }
2578 arraySize += ']';
2579 clang::QualType subArrQT = arrType->getElementType();
2580 if (subArrQT.isNull()) {
2581 std::string memberName;
2582 llvm::raw_string_ostream stream(memberName);
2583 // Don't trigger fopen of the source file to count lines:
2584 printPol.AnonymousTagLocations = false;
2585 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2586 stream.flush();
2587 Error("InspectMembers",
2588 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2589 arrLevel, subArrQT.getAsString(printPol).c_str(),
2590 memberName.c_str(), clname);
2591 haveErrorDueToArray = true;
2592 break;
2593 }
2594 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2595 }
2596 if (haveErrorDueToArray) {
2597 continue; // skip member
2598 }
2599
2600 // construct member name
2601 std::string fieldName;
2602 if (memType->isPointerType()) {
2603 fieldName = "*";
2604 }
2605
2606 // Check if this field has a custom ioname, if not, just use the one of the decl
2607 std::string ioname(iField->getName());
2608 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2609 fieldName += ioname;
2610 fieldName += arraySize;
2611
2612 // get member offset
2613 // NOTE currently we do not support bitfield and do not support
2614 // member that are not aligned on 'bit' boundaries.
2615 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2616 ptrdiff_t fieldOffset = offset.getQuantity();
2617
2618 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2619 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2620 // R__insp.InspectMember(fName, "fName.");
2621 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2622
2623 // If the class has a custom streamer and the type of the filed is a
2624 // private enum, struct or class, skip it.
2625 if (!insp.IsTreatingNonAccessibleTypes()){
2626 auto iFiledQtype = iField->getType();
2627 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2628 auto declAccess = tagDecl->getAccess();
2629 if (declAccess == AS_private || declAccess == AS_protected) {
2630 continue;
2631 }
2632 }
2633 }
2634
2635 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2636
2637 if (!ispointer) {
2638 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2639 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2640 // nested objects get an extra call to InspectMember
2641 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2642 std::string sFieldRecName;
2643 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2645 clang::QualType(memNonPtrType,0),
2646 *fInterpreter,
2648 }
2649
2650 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2651 // if we can not find the member (which should not really happen),
2652 // let's consider it transient.
2653 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2654
2655 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2656 (fieldName + '.').c_str(), transient);
2657
2658 }
2659 }
2660 } // loop over fields
2661
2662 // inspect bases
2663 // TNamed::ShowMembers(R__insp);
2664 unsigned iNBase = 0;
2665 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2666 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2667 iBase != eBase; ++iBase, ++iNBase) {
2668 clang::QualType baseQT = iBase->getType();
2669 if (baseQT.isNull()) {
2670 Error("InspectMembers",
2671 "Cannot find QualType for base number %d while inspecting class %s",
2672 iNBase, clname);
2673 continue;
2674 }
2675 const clang::CXXRecordDecl* baseDecl
2676 = baseQT->getAsCXXRecordDecl();
2677 if (!baseDecl) {
2678 Error("InspectMembers",
2679 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2680 iNBase, clname);
2681 continue;
2682 }
2683 TClass* baseCl=nullptr;
2684 std::string sBaseName;
2685 // Try with the DeclId
2686 std::vector<TClass*> foundClasses;
2687 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2688 if (foundClasses.size()==1){
2689 baseCl=foundClasses[0];
2690 } else {
2691 // Try with the normalised Name, as a fallback
2692 if (!baseCl){
2694 baseQT,
2695 *fInterpreter,
2697 baseCl = TClass::GetClass(sBaseName.c_str());
2698 }
2699 }
2700
2701 if (!baseCl){
2702 std::string qualNameForDiag;
2703 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2704 Error("InspectMembers",
2705 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2706 continue;
2707 }
2708
2709 int64_t baseOffset;
2710 if (iBase->isVirtual()) {
2712 if (!isTransient) {
2713 Error("InspectMembers",
2714 "Base %s of class %s is virtual but no object provided",
2715 sBaseName.c_str(), clname);
2716 }
2718 } else {
2719 // We have an object to determine the vbase offset.
2721 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
2722 if (ci && baseCi) {
2723 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
2724 true /*isDerivedObj*/);
2725 if (baseOffset == -1) {
2726 Error("InspectMembers",
2727 "Error calculating offset of virtual base %s of class %s",
2728 sBaseName.c_str(), clname);
2729 }
2730 } else {
2731 Error("InspectMembers",
2732 "Cannot calculate offset of virtual base %s of class %s",
2733 sBaseName.c_str(), clname);
2734 continue;
2735 }
2736 }
2737 } else {
2738 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
2739 }
2740 // TOFIX: baseCl can be null here!
2741 if (baseCl->IsLoaded()) {
2742 // For loaded class, CallShowMember will (especially for TObject)
2743 // call the virtual ShowMember rather than the class specific version
2744 // resulting in an infinite recursion.
2745 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
2746 } else {
2747 baseCl->CallShowMembers(cobj + baseOffset,
2748 insp, isTransient);
2749 }
2750 } // loop over bases
2751}
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// Reset the interpreter internal state in case a previous action was not correctly
2755/// terminated.
2756
2758{
2759 // No-op there is not equivalent state (to be cleared) in Cling.
2760}
2761
2762////////////////////////////////////////////////////////////////////////////////
2763/// Delete existing temporary values.
2764
2766{
2767 // No-op for cling due to cling::Value.
2768}
2769
2770////////////////////////////////////////////////////////////////////////////////
2771/// Declare code to the interpreter, without any of the interpreter actions
2772/// that could trigger a re-interpretation of the code. I.e. make cling
2773/// behave like a compiler: no dynamic lookup, no input wrapping for
2774/// subsequent execution, no automatic provision of declarations but just a
2775/// plain #include.
2776/// Returns true on success, false on failure.
2777
2778bool TCling::Declare(const char* code)
2779{
2781
2782 SuspendAutoloadingRAII autoLoadOff(this);
2783 SuspendAutoParsing autoParseRaii(this);
2784
2785 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
2786 fInterpreter->enableDynamicLookup(false);
2787 bool oldRawInput = fInterpreter->isRawInputEnabled();
2788 fInterpreter->enableRawInput(true);
2789
2790 Bool_t ret = LoadText(code);
2791
2792 fInterpreter->enableRawInput(oldRawInput);
2793 fInterpreter->enableDynamicLookup(oldDynLookup);
2794 return ret;
2795}
2796
2797////////////////////////////////////////////////////////////////////////////////
2798/// Enable the automatic loading of shared libraries when a class
2799/// is used that is stored in a not yet loaded library. Uses the
2800/// information stored in the class/library map (typically
2801/// $ROOTSYS/etc/system.rootmap).
2802
2804{
2805 if (fAllowLibLoad) {
2807 SetClassAutoloading(true);
2808 }
2809}
2810
2811////////////////////////////////////////////////////////////////////////////////
2812/// It calls a "fantom" method to synchronize user keyboard input
2813/// and ROOT prompt line.
2814
2816{
2818}
2819
2820// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
2821// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
2822// was already taking a lock.
2823static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
2824{
2825 // Check shared library.
2826 TString tLibName(libname);
2827 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
2828 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
2829 return false;
2830}
2831
2832Bool_t TCling::IsLibraryLoaded(const char* libname) const
2833{
2835 return s_IsLibraryLoaded(libname, fInterpreter);
2836}
2837
2838////////////////////////////////////////////////////////////////////////////////
2839/// Return true if ROOT has cxxmodules pcm for a given library name.
2840// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
2841Bool_t TCling::HasPCMForLibrary(const char *libname) const
2842{
2843 llvm::StringRef ModuleName(libname);
2844 ModuleName = llvm::sys::path::stem(ModuleName);
2845 ModuleName.consume_front("lib");
2846
2847 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
2848 clang::Module *M = moduleMap.findModule(ModuleName);
2849 return M && !M->IsMissingRequirement && M->getASTFile();
2850}
2851
2852////////////////////////////////////////////////////////////////////////////////
2853/// Return true if the file has already been loaded by cint.
2854/// We will try in this order:
2855/// actual filename
2856/// filename as a path relative to
2857/// the include path
2858/// the shared library path
2859
2860Bool_t TCling::IsLoaded(const char* filename) const
2861{
2863
2864 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
2865 // cling::DynamicLibraryManager.
2866
2867 std::string file_name = filename;
2868 size_t at = std::string::npos;
2869 while ((at = file_name.find("/./")) != std::string::npos)
2870 file_name.replace(at, 3, "/");
2871
2872 std::string filesStr = "";
2873 llvm::raw_string_ostream filesOS(filesStr);
2874 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
2875 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
2876 filesOS.flush();
2877
2878 llvm::SmallVector<llvm::StringRef, 100> files;
2879 llvm::StringRef(filesStr).split(files, "\n");
2880
2881 std::set<std::string> fileMap;
2882 // Fill fileMap; return early on exact match.
2883 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
2884 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
2885 if ((*iF) == file_name.c_str()) return kTRUE; // exact match
2886 fileMap.insert(*iF);
2887 }
2888
2889 if (fileMap.empty()) return kFALSE;
2890
2891 // Check MacroPath.
2892 TString sFilename(file_name.c_str());
2894 && fileMap.count(sFilename.Data())) {
2895 return kTRUE;
2896 }
2897
2898 // Check IncludePath.
2899 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
2900 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
2901 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
2902 while (incPath.Index(" :") != -1) {
2903 incPath.ReplaceAll(" :", ":");
2904 }
2905 incPath.Prepend(".:");
2906 sFilename = file_name.c_str();
2907 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
2908 && fileMap.count(sFilename.Data())) {
2909 return kTRUE;
2910 }
2911
2912 // Check shared library.
2913 if (s_IsLibraryLoaded(file_name.c_str(), fInterpreter))
2914 return kTRUE;
2915
2916 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
2917 const clang::DirectoryLookup *CurDir = 0;
2918 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
2919 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
2920 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
2921 clang::SourceLocation(),
2922 /*isAngled*/ false,
2923 /*FromDir*/ 0, CurDir,
2924 clang::ArrayRef<std::pair<const clang::FileEntry *,
2925 const clang::DirectoryEntry *>>(),
2926 /*SearchPath*/ 0,
2927 /*RelativePath*/ 0,
2928 /*RequestingModule*/ 0,
2929 /*SuggestedModule*/ 0,
2930 /*IsMapped*/ 0,
2931 /*SkipCache*/ false,
2932 /*BuildSystemModule*/ false,
2933 /*OpenFile*/ false,
2934 /*CacheFail*/ false);
2935 if (FE && FE->isValid()) {
2936 // check in the source manager if the file is actually loaded
2937 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
2938 // this works only with header (and source) files...
2939 clang::FileID FID = SM.translateFile(FE);
2940 if (!FID.isInvalid() && FID.getHashValue() == 0)
2941 return kFALSE;
2942 else {
2943 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
2944 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
2945 return kFALSE;
2946 if (!FID.isInvalid())
2947 return kTRUE;
2948 }
2949 // ...then check shared library again, but with full path now
2950 sFilename = FE->getName();
2951 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
2952 && fileMap.count(sFilename.Data())) {
2953 return kTRUE;
2954 }
2955 }
2956 return kFALSE;
2957}
2958
2959////////////////////////////////////////////////////////////////////////////////
2960
2962{
2963#if defined(R__WIN32) || defined(__CYGWIN__)
2964 HMODULE hModules[1024];
2965 void *hProcess;
2966 unsigned long cbModules;
2967 unsigned int i;
2968 hProcess = (void *)::GetCurrentProcess();
2969 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
2970 // start at 1 to skip the executable itself
2971 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
2972 static const int bufsize = 260;
2973 wchar_t winname[bufsize];
2974 char posixname[bufsize];
2975 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
2976#if defined(__CYGWIN__)
2977 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
2978#else
2979 std::wstring wpath = winname;
2980 std::replace(wpath.begin(), wpath.end(), '\\', '/');
2981 string path(wpath.begin(), wpath.end());
2982 strncpy(posixname, path.c_str(), bufsize);
2983#endif
2984 if (!fSharedLibs.Contains(posixname)) {
2985 RegisterLoadedSharedLibrary(posixname);
2986 }
2987 }
2988#elif defined(R__MACOSX)
2989 // fPrevLoadedDynLibInfo stores the *next* image index to look at
2990 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
2991
2992 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
2993 // Skip non-dylibs
2994 if (mh->filetype == MH_DYLIB) {
2995 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
2996 RegisterLoadedSharedLibrary(imageName);
2997 }
2998 }
2999
3000 ++imageIndex;
3001 }
3002 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3003#elif defined(R__LINUX)
3004 struct PointerNo4 {
3005 void* fSkip[3];
3006 void* fPtr;
3007 };
3008 struct LinkMap {
3009 void* fAddr;
3010 const char* fName;
3011 void* fLd;
3012 LinkMap* fNext;
3013 LinkMap* fPrev;
3014 };
3015 if (!fPrevLoadedDynLibInfo || fPrevLoadedDynLibInfo == (void*)(size_t)-1) {
3016 PointerNo4* procLinkMap = (PointerNo4*)dlopen(0, RTLD_LAZY | RTLD_GLOBAL);
3017 // 4th pointer of 4th pointer is the linkmap.
3018 // See http://syprog.blogspot.fr/2011/12/listing-loaded-shared-objects-in-linux.html
3019 LinkMap* linkMap = (LinkMap*) ((PointerNo4*)procLinkMap->fPtr)->fPtr;
3020 RegisterLoadedSharedLibrary(linkMap->fName);
3021 fPrevLoadedDynLibInfo = linkMap;
3022 // reduce use count of link map structure:
3023 dlclose(procLinkMap);
3024 }
3025
3026 LinkMap* iDyLib = (LinkMap*)fPrevLoadedDynLibInfo;
3027 while (iDyLib->fNext) {
3028 iDyLib = iDyLib->fNext;
3029 RegisterLoadedSharedLibrary(iDyLib->fName);
3030 }
3031 fPrevLoadedDynLibInfo = iDyLib;
3032#else
3033 Error("TCling::UpdateListOfLoadedSharedLibraries",
3034 "Platform not supported!");
3035#endif
3036}
3037
3038////////////////////////////////////////////////////////////////////////////////
3039/// Register a new shared library name with the interpreter; add it to
3040/// fSharedLibs.
3041
3042void TCling::RegisterLoadedSharedLibrary(const char* filename)
3043{
3044 // Ignore NULL filenames, aka "the process".
3045 if (!filename) return;
3046
3047 // Tell the interpreter that this library is available; all libraries can be
3048 // used to resolve symbols.
3049 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3050 if (!DLM->isLibraryLoaded(filename)) {
3051 DLM->loadLibrary(filename, true /*permanent*/);
3052 }
3053
3054#if defined(R__MACOSX)
3055 // Check that this is not a system library
3056 auto lenFilename = strlen(filename);
3057 if (!strncmp(filename, "/usr/lib/system/", 16)
3058 || !strncmp(filename, "/usr/lib/libc++", 15)
3059 || !strncmp(filename, "/System/Library/Frameworks/", 27)
3060 || !strncmp(filename, "/System/Library/PrivateFrameworks/", 34)
3061 || !strncmp(filename, "/System/Library/CoreServices/", 29)
3062 || !strcmp(filename, "cl_kernels") // yepp, no directory
3063 || strstr(filename, "/usr/lib/libSystem")
3064 || strstr(filename, "/usr/lib/libstdc++")
3065 || strstr(filename, "/usr/lib/libicucore")
3066 || strstr(filename, "/usr/lib/libbsm")
3067 || strstr(filename, "/usr/lib/libobjc")
3068 || strstr(filename, "/usr/lib/libresolv")
3069 || strstr(filename, "/usr/lib/libauto")
3070 || strstr(filename, "/usr/lib/libcups")
3071 || strstr(filename, "/usr/lib/libDiagnosticMessagesClient")
3072 || strstr(filename, "/usr/lib/liblangid")
3073 || strstr(filename, "/usr/lib/libCRFSuite")
3074 || strstr(filename, "/usr/lib/libpam")
3075 || strstr(filename, "/usr/lib/libOpenScriptingUtil")
3076 || strstr(filename, "/usr/lib/libextension")
3077 || strstr(filename, "/usr/lib/libAudioToolboxUtility")
3078 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3079 // /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3080 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3081 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3082 return;
3083#elif defined(__CYGWIN__)
3084 // Check that this is not a system library
3085 static const int bufsize = 260;
3086 char posixwindir[bufsize];
3087 char *windir = getenv("WINDIR");
3088 if (windir)
3089 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3090 else
3091 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3092 if (strstr(filename, posixwindir) ||
3093 strstr(filename, "/usr/bin/cyg"))
3094 return;
3095#elif defined(R__WIN32)
3096 if (strstr(filename, "/Windows/"))
3097 return;
3098#elif defined (R__LINUX)
3099 if (strstr(filename, "/ld-linux")
3100 || strstr(filename, "linux-gnu/")
3101 || strstr(filename, "/libstdc++.")
3102 || strstr(filename, "/libgcc")
3103 || strstr(filename, "/libc.")
3104 || strstr(filename, "/libdl.")
3105 || strstr(filename, "/libm."))
3106 return;
3107#endif
3108 // Update string of available libraries.
3109 if (!fSharedLibs.IsNull()) {
3110 fSharedLibs.Append(" ");
3111 }
3112 fSharedLibs.Append(filename);
3113}
3114
3115////////////////////////////////////////////////////////////////////////////////
3116/// Load a library file in cling's memory.
3117/// if 'system' is true, the library is never unloaded.
3118/// Return 0 on success, -1 on failure.
3119
3120Int_t TCling::Load(const char* filename, Bool_t system)
3121{
3122 if (!fAllowLibLoad) {
3123 Error("Load","Trying to load library (%s) from rootcling.",filename);
3124 return -1;
3125 }
3126
3127 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3129 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3130 std::string canonLib = DLM->lookupLibrary(filename);
3131 cling::DynamicLibraryManager::LoadLibResult res
3132 = cling::DynamicLibraryManager::kLoadLibNotFound;
3133 if (!canonLib.empty()) {
3134 if (system)
3135 res = DLM->loadLibrary(filename, system);
3136 else {
3137 // For the non system libs, we'd like to be able to unload them.
3138 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3139 cling::Interpreter::CompilationResult compRes;
3140 HandleInterpreterException(fMetaProcessor, Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3141 if (compRes == cling::Interpreter::kSuccess)
3142 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3143 }
3144 }
3145
3146 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3148 }
3149 switch (res) {
3150 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3151 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3152 default: break;
3153 };
3154 return -1;
3155}
3156
3157////////////////////////////////////////////////////////////////////////////////
3158/// Load a macro file in cling's memory.
3159
3160void TCling::LoadMacro(const char* filename, EErrorCode* error)
3161{
3162 ProcessLine(Form(".L %s", filename), error);
3163}
3164
3165////////////////////////////////////////////////////////////////////////////////
3166/// Let cling process a command line asynch.
3167
3169{
3170 return ProcessLine(line, error);
3171}
3172
3173////////////////////////////////////////////////////////////////////////////////
3174/// Let cling process a command line synchronously, i.e we are waiting
3175/// it will be finished.
3176
3178{
3180 if (gApplication) {
3181 if (gApplication->IsCmdThread()) {
3182 return ProcessLine(line, error);
3183 }
3184 return 0;
3185 }
3186 return ProcessLine(line, error);
3187}
3188
3189////////////////////////////////////////////////////////////////////////////////
3190/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3191/// however not declarations, like "Int_t x;").
3192
3194{
3195#ifdef R__WIN32
3196 // Test on ApplicationImp not being 0 is needed because only at end of
3197 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3198 // we can not use it.
3200 while (gROOT->IsLineProcessing() && !gApplication) {
3201 Warning("Calc", "waiting for cling thread to free");
3202 gSystem->Sleep(500);
3203 }
3204 gROOT->SetLineIsProcessing();
3205 }
3206#endif // R__WIN32
3208 if (error) {
3209 *error = TInterpreter::kNoError;
3210 }
3211 cling::Value valRef;
3212 cling::Interpreter::CompilationResult cr = fInterpreter->evaluate(line, valRef);
3213 if (cr != cling::Interpreter::kSuccess) {
3214 // Failure in compilation.
3215 if (error) {
3216 // Note: Yes these codes are weird.
3218 }
3219 return 0L;
3220 }
3221 if (!valRef.isValid()) {
3222 // Failure at runtime.
3223 if (error) {
3224 // Note: Yes these codes are weird.
3225 *error = TInterpreter::kDangerous;
3226 }
3227 return 0L;
3228 }
3229
3230 if (valRef.isVoid()) {
3231 return 0;
3232 }
3233
3234 RegisterTemporary(valRef);
3235#ifdef R__WIN32
3237 gROOT->SetLineHasBeenProcessed();
3238 }
3239#endif // R__WIN32
3240 return valRef.simplisticCastAs<long>();
3241}
3242
3243////////////////////////////////////////////////////////////////////////////////
3244/// Set a getline function to call when input is needed.
3245
3246void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3247 void (*histaddFunc)(const char* line))
3248{
3249 // If cling offers a replacement for G__pause(), it would need to
3250 // also offer a way to customize at least the history recording.
3251
3252#if defined(R__MUST_REVISIT)
3253#if R__MUST_REVISIT(6,2)
3254 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3255#endif
3256#endif
3257}
3258
3259////////////////////////////////////////////////////////////////////////////////
3260/// Helper function to increase the internal Cling count of transactions
3261/// that change the AST.
3262
3263Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3264{
3266
3267 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3268 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3269 || T.macros_begin() != T.macros_end()
3270 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3272 return true;
3273 }
3274 return false;
3275}
3276
3277////////////////////////////////////////////////////////////////////////////////
3278/// Delete object from cling symbol table so it can not be used anymore.
3279/// cling objects are always on the heap.
3280
3282{
3283 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3284 // put in place the Read/Write part here. Keeping the write lock
3285 // here is 'catasptrophic' for scaling as it means that ALL calls
3286 // to RecursiveRemove will take the write lock and performance
3287 // of many threads trying to access the write lock at the same
3288 // time is relatively bad.
3290 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3291 // (but isn't at the moment).
3292 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3293 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3294 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3296 DeleteGlobal(obj);
3297 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3298 }
3299 }
3300}
3301
3302////////////////////////////////////////////////////////////////////////////////
3303/// Pressing Ctrl+C should forward here. In the case where we have had
3304/// continuation requested we must reset it.
3305
3307{
3308 fMetaProcessor->cancelContinuation();
3309 // Reset the Cling state to the state saved by the last call to
3310 // TCling::SaveContext().
3311#if defined(R__MUST_REVISIT)
3312#if R__MUST_REVISIT(6,2)
3314 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3315#endif
3316#endif
3317}
3318
3319////////////////////////////////////////////////////////////////////////////////
3320/// Reset the Cling state to its initial state.
3321
3323{
3324#if defined(R__MUST_REVISIT)
3325#if R__MUST_REVISIT(6,2)
3327 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3328#endif
3329#endif
3330}
3331
3332////////////////////////////////////////////////////////////////////////////////
3333/// Reset in Cling the list of global variables to the state saved by the last
3334/// call to TCling::SaveGlobalsContext().
3335///
3336/// Note: Right now, all we do is run the global destructors.
3337
3339{
3341 // TODO:
3342 // Here we should iterate over the transactions (N-3) and revert.
3343 // N-3 because the first three internal to cling.
3344
3345 fInterpreter->runAndRemoveStaticDestructors();
3346}
3347
3348////////////////////////////////////////////////////////////////////////////////
3349/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3350/// call to TCling::SaveGlobalsContext().
3351
3353{
3354#if defined(R__MUST_REVISIT)
3355#if R__MUST_REVISIT(6,2)
3357 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3358#endif
3359#endif
3360}
3361
3362////////////////////////////////////////////////////////////////////////////////
3363/// Rewind Cling dictionary to the point where it was before executing
3364/// the current macro. This function is typically called after SEGV or
3365/// ctlr-C after doing a longjmp back to the prompt.
3366
3368{
3369#if defined(R__MUST_REVISIT)
3370#if R__MUST_REVISIT(6,2)
3372 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3373#endif
3374#endif
3375}
3376
3377////////////////////////////////////////////////////////////////////////////////
3378/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3379/// Returns 1 in case of success and 0 in case object was not in table.
3380
3382{
3383#if defined(R__MUST_REVISIT)
3384#if R__MUST_REVISIT(6,2)
3386 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3387#endif
3388#endif
3389 return 0;
3390}
3391
3392////////////////////////////////////////////////////////////////////////////////
3393/// Undeclare obj called name.
3394/// Returns 1 in case of success, 0 for failure.
3395
3397{
3398#if defined(R__MUST_REVISIT)
3399#if R__MUST_REVISIT(6,2)
3400 Warning("DeleteVariable","should do more that just reseting the value to zero");
3401#endif
3402#endif
3403
3405 llvm::StringRef srName(name);
3406 const char* unscopedName = name;
3407 llvm::StringRef::size_type posScope = srName.rfind("::");
3408 const clang::DeclContext* declCtx = 0;
3409 if (posScope != llvm::StringRef::npos) {
3410 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3411 const clang::Decl* scopeDecl
3412 = lh.findScope(srName.substr(0, posScope),
3413 cling::LookupHelper::WithDiagnostics);
3414 if (!scopeDecl) {
3415 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3416 name);
3417 return 0;
3418 }
3419 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3420 if (!declCtx) {
3421 Error("DeleteVariable",
3422 "Enclosing scope for variable %s is not a declaration context",
3423 name);
3424 return 0;
3425 }
3426 unscopedName += posScope + 2;
3427 }
3428 // Could trigger deserialization of decls.
3429 cling::Interpreter::PushTransactionRAII RAII(fInterpreter);
3430 clang::NamedDecl* nVarDecl
3431 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3432 if (!nVarDecl) {
3433 Error("DeleteVariable", "Unknown variable %s", name);
3434 return 0;
3435 }
3436 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3437 if (!varDecl) {
3438 Error("DeleteVariable", "Entity %s is not a variable", name);
3439 return 0;
3440 }
3441
3442 clang::QualType qType = varDecl->getType();
3443 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3444 // Cannot set a reference's address to nullptr; the JIT can place it
3445 // into read-only memory (ROOT-7100).
3446 if (type->isPointerType()) {
3447 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3448 // set pointer to invalid.
3449 if (ppInt) *ppInt = 0;
3450 }
3451 return 1;
3452}
3453
3454////////////////////////////////////////////////////////////////////////////////
3455/// Save the current Cling state.
3456
3458{
3459#if defined(R__MUST_REVISIT)
3460#if R__MUST_REVISIT(6,2)
3462 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3463#endif
3464#endif
3465}
3466
3467////////////////////////////////////////////////////////////////////////////////
3468/// Save the current Cling state of global objects.
3469
3471{
3472#if defined(R__MUST_REVISIT)
3473#if R__MUST_REVISIT(6,2)
3475 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3476#endif
3477#endif
3478}
3479
3480////////////////////////////////////////////////////////////////////////////////
3481/// No op: see TClingCallbacks (used to update the list of globals)
3482
3484{
3485}
3486
3487////////////////////////////////////////////////////////////////////////////////
3488/// No op: see TClingCallbacks (used to update the list of global functions)
3489
3491{
3492}
3493
3494////////////////////////////////////////////////////////////////////////////////
3495/// No op: see TClingCallbacks (used to update the list of types)
3496
3498{
3499}
3500
3501////////////////////////////////////////////////////////////////////////////////
3502/// Check in what order the member of a tuple are layout.
3503enum class ETupleOrdering {
3504 kAscending,
3507};
3508
3509struct AlternateTupleIntDoubleAsc
3510{
3511 Int_t _0;
3512 Double_t _1;
3513};
3514
3515struct AlternateTupleIntDoubleDes
3516{
3517 Double_t _1;
3518 Int_t _0;
3519};
3520
3522{
3523 std::tuple<int,double> value;
3524 AlternateTupleIntDoubleAsc asc;
3525 AlternateTupleIntDoubleDes des;
3526
3527 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3528 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3529
3530 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3531 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3532
3533 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3534 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3535
3536 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3538 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3540 } else {
3542 }
3543}
3544
3545std::string AlternateTuple(const char *classname)
3546{
3547 TClassEdit::TSplitType tupleContent(classname);
3548 std::string alternateName = "TEmulatedTuple";
3549 alternateName.append( classname + 5 );
3550
3551 std::string guard_name;
3552 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3553 std::ostringstream guard;
3554 guard << "ROOT_INTERNAL_TEmulated_";
3555 guard << guard_name;
3556
3557 std::ostringstream alternateTuple;
3558 alternateTuple << "#ifndef " << guard.str() << "\n";
3559 alternateTuple << "#define " << guard.str() << "\n";
3560 alternateTuple << "namespace ROOT { namespace Internal {\n";
3561 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3562 alternateTuple << "template <> struct " << alternateName << " {\n";
3563
3564 // This could also be a compile time choice ...
3565 switch(IsTupleAscending()) {
3567 unsigned int nMember = 0;
3568 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3569 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3570 while (iter != theEnd) {
3571 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3572 ++iter;
3573 ++nMember;
3574 }
3575 break;
3576 }
3578 unsigned int nMember = tupleContent.fElements.size() - 3;
3579 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3580 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3581 while (iter != theEnd) {
3582 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3583 ++iter;
3584 --nMember;
3585 }
3586 break;
3587 }
3589 Fatal("TCling::SetClassInfo::AlternateTuple",
3590 "Layout of std::tuple on this platform is unexpected.");
3591 break;
3592 }
3593 }
3594
3595 alternateTuple << "};\n";
3596 alternateTuple << "}}\n";
3597 alternateTuple << "#endif\n";
3598 if (!gCling->Declare(alternateTuple.str().c_str())) {
3599 Error("Load","Could not declare %s",alternateName.c_str());
3600 return "";
3601 }
3602 alternateName = "ROOT::Internal::" + alternateName;
3603 return alternateName;
3604}
3605
3606////////////////////////////////////////////////////////////////////////////////
3607/// Set pointer to the TClingClassInfo in TClass.
3608/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3609/// already have one.
3610
3612{
3613 // We are shutting down, there is no point in reloading, it only triggers
3614 // redundant deserializations.
3615 if (fIsShuttingDown) {
3616 // Remove the decl_id from the DeclIdToTClass map
3617 if (cl->fClassInfo) {
3619 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3620 // Test again as another thread may have set fClassInfo to nullptr.
3621 if (TClinginfo) {
3622 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3623 }
3624 delete TClinginfo;
3625 cl->fClassInfo = nullptr;
3626 }
3627 return;
3628 }
3629
3631 if (cl->fClassInfo && !reload) {
3632 return;
3633 }
3634 //Remove the decl_id from the DeclIdToTClass map
3635 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3636 if (TClinginfo) {
3637 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3638 }
3639 delete TClinginfo;
3640 cl->fClassInfo = 0;
3641 std::string name(cl->GetName());
3642
3643 // Handle the special case of 'tuple' where we ignore the real implementation
3644 // details and just overlay a 'simpler'/'simplistic' version that is easy
3645 // for the I/O to understand and handle.
3646 if (!(fCxxModulesEnabled && IsFromRootCling()) && strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
3647
3648 name = AlternateTuple(cl->GetName());
3649
3650 }
3651
3652 TClingClassInfo* info = new TClingClassInfo(fInterpreter, name.c_str());
3653 if (!info->IsValid()) {
3654 if (cl->fState != TClass::kHasTClassInit) {
3655 if (cl->fStreamerInfo->GetEntries() != 0) {
3657 } else {
3659 }
3660 }
3661 delete info;
3662 return;
3663 }
3664 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
3665 // In case a class contains an external enum, the enum will be seen as a
3666 // class. We must detect this special case and make the class a Zombie.
3667 // Here we assume that a class has at least one method.
3668 // We can NOT call TClass::Property from here, because this method
3669 // assumes that the TClass is well formed to do a lot of information
3670 // caching. The method SetClassInfo (i.e. here) is usually called during
3671 // the building phase of the TClass, hence it is NOT well formed yet.
3672 Bool_t zombieCandidate = kFALSE;
3673 if (
3674 info->IsValid() &&
3675 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
3676 ) {
3677 zombieCandidate = kTRUE;
3678 }
3679 if (!info->IsLoaded()) {
3680 if (info->Property() & (kIsNamespace)) {
3681 // Namespaces can have info but no corresponding CINT dictionary
3682 // because they are auto-created if one of their contained
3683 // classes has a dictionary.
3684 zombieCandidate = kTRUE;
3685 }
3686 // this happens when no dictionary is available
3687 delete info;
3688 cl->fClassInfo = 0;
3689 }
3690 if (zombieCandidate && !cl->GetCollectionType()) {
3691 cl->MakeZombie();
3692 }
3693 // If we reach here, the info was valid (See early returns).
3694 if (cl->fState != TClass::kHasTClassInit) {
3695 if (cl->fClassInfo) {
3698 } else {
3699// if (TClassEdit::IsSTLCont(cl->GetName()) {
3700// There will be an emulated collection proxy, is that the same?
3701// cl->fState = TClass::kEmulated;
3702// } else {
3703 if (cl->fStreamerInfo->GetEntries() != 0) {
3705 } else {
3707 }
3708// }
3709 }
3710 }
3711 if (cl->fClassInfo) {
3712 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
3713 }
3714}
3715
3716////////////////////////////////////////////////////////////////////////////////
3717/// Checks if an entity with the specified name is defined in Cling.
3718/// Returns kUnknown if the entity is not defined.
3719/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
3720/// Returns kKnown if the entity is defined.
3721///
3722/// By default, structs, namespaces, classes, enums and unions are looked for.
3723/// If the flag isClassOrNamespaceOnly is true, classes, structs and
3724/// namespaces only are considered. I.e. if the name is an enum or a union,
3725/// the returned value is false.
3726///
3727/// In the case where the class is not loaded and belongs to a namespace
3728/// or is nested, looking for the full class name is outputting a lots of
3729/// (expected) error messages. Currently the only way to avoid this is to
3730/// specifically check that each level of nesting is already loaded.
3731/// In case of templates the idea is that everything between the outer
3732/// '<' and '>' has to be skipped, e.g.: aap<pippo<noot>::klaas>::a_class
3733
3735TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
3736{
3738 static const char *anonEnum = "anonymous enum ";
3739 static const int cmplen = strlen(anonEnum);
3740
3741 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
3742 return kUnknown;
3743 }
3744
3745 // Avoid the double search below in case the name is a fundamental type
3746 // or typedef to a fundamental type.
3747 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
3748 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
3749
3750 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
3751 && fundType->GetType() > 0) {
3752 // Fundamental type, no a class.
3753 return kUnknown;
3754 }
3755
3756 // Migrated from within TClass::GetClass
3757 // If we want to know if a class or a namespace with this name exists in the
3758 // interpreter and this is an enum in the type system, before or after loading
3759 // according to the autoload function argument, return kUnknown.
3760 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
3761 return kUnknown;
3762
3763 const char *classname = name;
3764
3765 int storeAutoload = SetClassAutoloading(autoload);
3766
3767 // First we want to check whether the decl exist, but _without_
3768 // generating any template instantiation. However, the lookup
3769 // still will create a forward declaration of the class template instance
3770 // if it exist. In this case, the return value of findScope will still
3771 // be zero but the type will be initialized.
3772 // Note in the corresponding code in ROOT 5, CINT was not instantiating
3773 // this forward declaration.
3774 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3775 const clang::Type *type = 0;
3776 const clang::Decl *decl
3777 = lh.findScope(classname,
3778 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3779 : cling::LookupHelper::NoDiagnostics,
3780 &type, /* intantiateTemplate= */ false );
3781 if (!decl) {
3782 std::string buf = TClassEdit::InsertStd(classname);
3783 decl = lh.findScope(buf,
3784 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3785 : cling::LookupHelper::NoDiagnostics,
3786 &type,false);
3787 }
3788
3789 if (type) {
3790 // If decl==0 and the type is valid, then we have a forward declaration.
3791 if (!decl) {
3792 // If we have a forward declaration for a class template instantiation,
3793 // we want to ignore it if it was produced/induced by the call to
3794 // findScope, however we can not distinguish those from the
3795 // instantiation induce by 'soft' use (and thus also induce by the
3796 // same underlying code paths)
3797 // ['soft' use = use not requiring a complete definition]
3798 // So to reduce the amount of disruption to the existing code we
3799 // would just ignore those for STL collection, for which we really
3800 // need to have the compiled collection proxy (and thus the TClass
3801 // bootstrap).
3802 clang::ClassTemplateSpecializationDecl *tmpltDecl =
3803 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
3804 (type->getAsCXXRecordDecl());
3805 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
3806 // Since the point of instantiation is invalid, we 'guess' that
3807 // the 'instantiation' of the forwarded type appended in
3808 // findscope.
3809 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
3810 // For STL Collection we return kUnknown.
3811 SetClassAutoloading(storeAutoload);
3812 return kUnknown;
3813 }
3814 }
3815 }
3817 if (!tci.IsValid()) {
3818 SetClassAutoloading(storeAutoload);
3819 return kUnknown;
3820 }
3821 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
3823
3824 if (tci.Property() & propertiesMask) {
3825 bool hasClassDefInline = false;
3826 if (isClassOrNamespaceOnly) {
3827 // We do not need to check for ClassDefInline when this is called from
3828 // TClass::Init, we only do it for the call from TClass::GetClass.
3829 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
3830 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
3831
3832 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
3833 int lineNumber = 0;
3834 bool success = false;
3835 std::tie(success, lineNumber) =
3836 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetMethodDecl(), *fInterpreter);
3837 hasClassDefInline = success && (lineNumber == -1);
3838 }
3839 }
3840
3841 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
3842 // , hasClassDefInline);
3843
3844 // We are now sure that the entry is not in fact an autoload entry.
3845 SetClassAutoloading(storeAutoload);
3846 if (hasClassDefInline)
3847 return kWithClassDefInline;
3848 else
3849 return kKnown;
3850 } else {
3851 // We are now sure that the entry is not in fact an autoload entry.
3852 SetClassAutoloading(storeAutoload);
3853 return kUnknown;
3854 }
3855 }
3856
3857 SetClassAutoloading(storeAutoload);
3858 if (decl)
3859 return kKnown;
3860 else
3861 return kUnknown;
3862
3863 // Setting up iterator part of TClingTypedefInfo is too slow.
3864 // Copy the lookup code instead:
3865 /*
3866 TClingTypedefInfo t(fInterpreter, name);
3867 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
3868 delete[] classname;
3869 SetClassAutoloading(storeAutoload);
3870 return kTRUE;
3871 }
3872 */
3873
3874// const clang::Decl *decl = lh.findScope(name);
3875// if (!decl) {
3876// std::string buf = TClassEdit::InsertStd(name);
3877// decl = lh.findScope(buf);
3878// }
3879
3880// SetClassAutoloading(storeAutoload);
3881// return (decl);
3882}
3883
3884////////////////////////////////////////////////////////////////////////////////
3885/// Return true if there is a class template by the given name ...
3886
3888{
3889 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3890 const clang::Decl *decl
3891 = lh.findClassTemplate(name,
3892 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3893 : cling::LookupHelper::NoDiagnostics);
3894 if (!decl) {
3895 std::string strname = "std::";
3896 strname += name;
3897 decl = lh.findClassTemplate(strname,
3898 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3899 : cling::LookupHelper::NoDiagnostics);
3900 }
3901 return 0 != decl;
3902}
3903
3904////////////////////////////////////////////////////////////////////////////////
3905/// Create list of pointers to base class(es) for TClass cl.
3906
3908{
3910 if (cl->fBase) {
3911 return;
3912 }
3914 if (!tci) return;
3916 TList *listOfBase = new TList;
3917 while (t.Next()) {
3918 // if name cannot be obtained no use to put in list
3919 if (t.IsValid() && t.Name()) {
3921 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
3922 }
3923 }
3924 // Now that is complete, publish it.
3925 cl->fBase = listOfBase;
3926}
3927
3928////////////////////////////////////////////////////////////////////////////////
3929/// Create list of pointers to enums for TClass cl.
3930
3931void TCling::LoadEnums(TListOfEnums& enumList) const
3932{
3934
3935 const Decl * D;
3936 TClass* cl = enumList.GetClass();
3937 if (cl) {
3938 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
3939 }
3940 else {
3941 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
3942 }
3943 // Iterate on the decl of the class and get the enums.
3944 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
3945 cling::Interpreter::PushTransactionRAII deserRAII(fInterpreter);
3946 // Collect all contexts of the namespace.
3947 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
3948 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
3949 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
3950 declIter != declEnd; ++declIter) {
3951 // Iterate on all decls for each context.
3952 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
3953 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
3954 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
3955 // Get name of the enum type.
3956 std::string buf;
3957 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
3958 llvm::raw_string_ostream stream(buf);
3959 // Don't trigger fopen of the source file to count lines:
3960 Policy.AnonymousTagLocations = false;
3961 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
3962 stream.flush();
3963 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
3964 if (!buf.empty()) {
3965 const char* name = buf.c_str();
3966 // Add the enum to the list of loaded enums.
3967 enumList.Get(ED, name);
3968 }
3969 }
3970 }
3971 }
3972 }
3973}
3974
3975////////////////////////////////////////////////////////////////////////////////
3976/// Create list of pointers to function templates for TClass cl.
3977
3979{
3981
3982 const Decl * D;
3983 TListOfFunctionTemplates* funcTempList;
3984 if (cl) {
3985 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
3986 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
3987 }
3988 else {
3989 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
3990 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
3991 }
3992 // Iterate on the decl of the class and get the enums.
3993 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
3994 cling::Interpreter::PushTransactionRAII deserRAII(fInterpreter);
3995 // Collect all contexts of the namespace.
3996 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
3997 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
3998 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
3999 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4000 // Iterate on all decls for each context.
4001 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4002 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4003 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4004 funcTempList->Get(FTD);
4005 }
4006 }
4007 }
4008 }
4009}
4010
4011////////////////////////////////////////////////////////////////////////////////
4012/// Get the scopes representing using declarations of namespace
4013
4014std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4015{
4017 return ci->GetUsingNamespaces();
4018}
4019
4020////////////////////////////////////////////////////////////////////////////////
4021/// Create list of pointers to data members for TClass cl.
4022/// This is now a nop. The creation and updating is handled in
4023/// TListOfDataMembers.
4024
4026{
4027}
4028
4029////////////////////////////////////////////////////////////////////////////////
4030/// Create list of pointers to methods for TClass cl.
4031/// This is now a nop. The creation and updating is handled in
4032/// TListOfFunctions.
4033
4035{
4036}
4037
4038////////////////////////////////////////////////////////////////////////////////
4039/// Update the list of pointers to method for TClass cl
4040/// This is now a nop. The creation and updating is handled in
4041/// TListOfFunctions.
4042
4044{
4045}
4046
4047////////////////////////////////////////////////////////////////////////////////
4048/// Update the list of pointers to data members for TClass cl
4049/// This is now a nop. The creation and updating is handled in
4050/// TListOfDataMembers.
4051
4053{
4054}
4055
4056////////////////////////////////////////////////////////////////////////////////
4057/// Create list of pointers to method arguments for TMethod m.
4058
4060{
4062 if (m->fMethodArgs) {
4063 return;
4064 }
4065 TList *arglist = new TList;
4067 while (t.Next()) {
4068 if (t.IsValid()) {
4070 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4071 }
4072 }
4073 m->fMethodArgs = arglist;
4074}
4075
4076
4077////////////////////////////////////////////////////////////////////////////////
4078/// Generate a TClass for the given class.
4079/// Since the caller has already check the ClassInfo, let it give use the
4080/// result (via the value of emulation) rather than recalculate it.
4081
4082TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4083{
4084// For now the following line would lead to the (unwanted) instantiation
4085// of class template. This could/would need to be resurrected only if
4086// we re-introduce so sort of automatic instantiation. However this would
4087// have to include carefull look at the template parameter to avoid
4088// creating instance we can not really use (if the parameter are only forward
4089// declaration or do not have all the necessary interfaces).
4090
4091 // TClingClassInfo tci(fInterpreter, classname);
4092 // if (1 || !tci.IsValid()) {
4093
4094 Version_t version = 1;
4095 if (TClassEdit::IsSTLCont(classname)) {
4096 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4097 }
4098 TClass *cl = new TClass(classname, version, silent);
4099 if (emulation) {
4101 } else {
4102 // Set the class version if the class is versioned.
4103 // Note that we cannot just call CLASS::Class_Version() as we might not have
4104 // an execution engine (when invoked from rootcling).
4105
4106 // Do not call cl->GetClassVersion(), it has side effects!
4107 Version_t oldvers = cl->fClassVersion;
4108 if (oldvers == version && cl->GetClassInfo()) {
4109 // We have a version and it might need an update.
4110 Version_t newvers = oldvers;
4112 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4113 // Namespaces don't have class versions.
4114 return cl;
4115 }
4116 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4119 if (!mi.IsValid()) {
4120 if (cl->TestBit(TClass::kIsTObject)) {
4121 Error("GenerateTClass",
4122 "Cannot find %s::Class_Version()! Class version might be wrong.",
4123 cl->GetName());
4124 }
4125 return cl;
4126 }
4127 newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4128 *fInterpreter);
4129 if (newvers == -1) {
4130 // Didn't manage to determine the class version from the AST.
4131 // Use runtime instead.
4132 if ((mi.Property() & kIsStatic)
4133 && !fInterpreter->isInSyntaxOnlyMode()) {
4134 // This better be a static function.
4136 callfunc.SetFunc(&mi);
4137 newvers = callfunc.ExecInt(0);
4138 } else {
4139 Error("GenerateTClass",
4140 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4141 cl->GetName());
4142 }
4143 }
4144 if (newvers != oldvers) {
4145 cl->fClassVersion = newvers;
4146 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4147 }
4148 }
4149 }
4150
4151 return cl;
4152
4153// } else {
4154// return GenerateTClass(&tci,silent);
4155// }
4156}
4157
4158#if 0
4159////////////////////////////////////////////////////////////////////////////////
4160
4161static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4162{
4163 includes += info->FileName();
4164
4165 const clang::ClassTemplateSpecializationDecl *templateCl
4166 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4167 if (templateCl) {
4168 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4169 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4170 if (arg.getKind() == clang::TemplateArgument::Type) {
4171 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4172
4173 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4174 // We really need a header file.
4175 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4176 if (argdecl) {
4177 includes += ";";
4178 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4179 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4180 } else {
4181 std::string Result;
4182 llvm::raw_string_ostream OS(Result);
4183 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4184 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4185 }
4186 }
4187 }
4188 }
4189 }
4190}
4191#endif
4192
4193////////////////////////////////////////////////////////////////////////////////
4194/// Generate a TClass for the given class.
4195
4196TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4197{
4198 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4199 if (!info || !info->IsValid()) {
4200 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4201 return 0;
4202 }
4203 // We are in the case where we have AST nodes for this class.
4204 TClass *cl = 0;
4205 std::string classname;
4206 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4207 if (TClassEdit::IsSTLCont(classname)) {
4208#if 0
4209 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4210 // We need to build up the list of required headers, by
4211 // looking at each template arguments.
4212 TString includes;
4213 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4214
4215 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4216 // 0 means success.
4217 cl = TClass::LoadClass(classnam.c_str(), silent);
4218 if (cl == 0) {
4219 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4220 }
4221 }
4222#endif
4223 if (cl == 0) {
4224 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4225 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4227 }
4228 } else {
4229 // For regular class, just create a TClass on the fly ...
4230 // Not quite useful yet, but that what CINT used to do anyway.
4231 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4232 }
4233 // Add the new TClass to the map of declid and TClass*.
4234 if (cl) {
4236 }
4237 return cl;
4238}
4239
4240////////////////////////////////////////////////////////////////////////////////
4241/// Generate the dictionary for the C++ classes listed in the first
4242/// argument (in a semi-colon separated list).
4243/// 'includes' contains a semi-colon separated list of file to
4244/// #include in the dictionary.
4245/// For example:
4246/// ~~~ {.cpp}
4247/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4248/// ~~~
4249/// or
4250/// ~~~ {.cpp}
4251/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4252/// ~~~
4253
4254Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4255{
4256 if (classes == 0 || classes[0] == 0) {
4257 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4258 return 0;
4259 }
4260 // Split the input list
4261 std::vector<std::string> listClasses;
4262 for (
4263 const char* current = classes, *prev = classes;
4264 *current != 0;
4265 ++current
4266 ) {
4267 if (*current == ';') {
4268 listClasses.push_back(std::string(prev, current - prev));
4269 prev = current + 1;
4270 }
4271 else if (*(current + 1) == 0) {
4272 listClasses.push_back(std::string(prev, current + 1 - prev));
4273 prev = current + 1;
4274 }
4275 }
4276 std::vector<std::string> listIncludes;
4277 if (!includes)
4278 includes = "";
4279 for (
4280 const char* current = includes, *prev = includes;
4281 *current != 0;
4282 ++current
4283 ) {
4284 if (*current == ';') {
4285 listIncludes.push_back(std::string(prev, current - prev));
4286 prev = current + 1;
4287 }
4288 else if (*(current + 1) == 0) {
4289 listIncludes.push_back(std::string(prev, current + 1 - prev));
4290 prev = current + 1;
4291 }
4292 }
4293 // Generate the temporary dictionary file
4294 return !TCling_GenerateDictionary(listClasses, listIncludes,
4295 std::vector<std::string>(), std::vector<std::string>());
4296}
4297
4298////////////////////////////////////////////////////////////////////////////////
4299/// Return pointer to cling Decl of global/static variable that is located
4300/// at the address given by addr.
4301
4302TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4303{
4305 DeclId_t d;
4306 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4307
4308 if (cl) {
4309 d = cl->GetDataMember(name);
4310 // We check if the decl of the data member has an annotation which indicates
4311 // an ioname.
4312 // In case this is true, if the name requested is not the ioname, we
4313 // return 0, as if the member did not exist. In some sense we override
4314 // the information in the TClassInfo instance, isolating the typesystem in
4315 // TClass from the one in the AST.
4316 if (const ValueDecl* decl = (const ValueDecl*) d){
4317 std::string ioName;
4318 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4319 if (hasIoName && ioName != name) return 0;
4320 }
4321 return d;
4322 }
4323 // We are looking up for something on the TU scope.
4324 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4325 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4326 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4327 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4328 // are only fulfilling ROOT's understanding for a Data Member.
4329 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4330 // similar as below.
4331 using namespace clang;
4332 Sema& SemaR = fInterpreter->getSema();
4333 DeclarationName DName = &SemaR.Context.Idents.get(name);
4334
4335 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4336 Sema::ForRedeclaration);
4337
4338 // Could trigger deserialization of decls.
4339 cling::Interpreter::PushTransactionRAII RAII(fInterpreter);
4340 cling::utils::Lookup::Named(&SemaR, R);
4341
4342 LookupResult::Filter F = R.makeFilter();
4343 // Filter the data-member looking decls.
4344 while (F.hasNext()) {
4345 NamedDecl *D = F.next();
4346 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4347 isa<IndirectFieldDecl>(D))
4348 continue;
4349 F.erase();
4350 }
4351 F.done();
4352
4353 if (R.isSingleResult())
4354 return R.getFoundDecl();
4355 return 0;
4356}
4357
4358////////////////////////////////////////////////////////////////////////////////
4359/// Return pointer to cling Decl of global/static variable that is located
4360/// at the address given by addr.
4361
4363{
4365
4366 const clang::Decl* possibleEnum = 0;
4367 // FInd the context of the decl.
4368 if (cl) {
4370 if (cci) {
4371 const clang::DeclContext* dc = 0;
4372 if (const clang::Decl* D = cci->GetDecl()) {
4373 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4374 dc = dyn_cast<clang::RecordDecl>(D);
4375 }
4376 }
4377 if (dc) {
4378 // If it is a data member enum.
4379 // Could trigger deserialization of decls.
4380 cling::Interpreter::PushTransactionRAII RAII(fInterpreter);
4381 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4382 } else {
4383 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4384 }
4385 }
4386 } else {
4387 // If it is a global enum.
4388 // Could trigger deserialization of decls.
4389 cling::Interpreter::PushTransactionRAII RAII(fInterpreter);
4390 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4391 }
4392 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4393 && isa<clang::EnumDecl>(possibleEnum)) {
4394 return possibleEnum;
4395 }
4396 return 0;
4397}
4398
4399////////////////////////////////////////////////////////////////////////////////
4400/// Return pointer to cling DeclId for a global value
4401
4402TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4403{
4404 if (!gv) return 0;
4405
4406 llvm::StringRef mangled_name = gv->getName();
4407
4408 int err = 0;
4409 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4410 if (err) {
4411 if (err == -2) {
4412 // It might simply be an unmangled global name.
4413 DeclId_t d;
4415 d = gcl.GetDataMember(mangled_name.str().c_str());
4416 return d;
4417 }
4418 return 0;
4419 }
4420
4421 std::string scopename(demangled_name_c);
4422 free(demangled_name_c);
4423
4424 //
4425 // Separate out the class or namespace part of the
4426 // function name.
4427 //
4428 std::string dataname;
4429
4430 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4431 scopename.erase(0, sizeof("typeinfo for ")-1);
4432 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4433 scopename.erase(0, sizeof("vtable for ")-1);
4434 } else {
4435 // See if it is a function
4436 std::string::size_type pos = scopename.rfind('(');
4437 if (pos != std::string::npos) {
4438 return 0;
4439 }
4440 // Separate the scope and member name
4441 pos = scopename.rfind(':');
4442 if (pos != std::string::npos) {
4443 if ((pos != 0) && (scopename[pos-1] == ':')) {
4444 dataname = scopename.substr(pos+1);
4445 scopename.erase(pos-1);
4446 }
4447 } else {
4448 scopename.clear();
4449 dataname = scopename;
4450 }
4451 }
4452 //fprintf(stderr, "name: '%s'\n", name.c_str());
4453 // Now we have the class or namespace name, so do the lookup.
4454
4455
4456 DeclId_t d;
4457 if (scopename.size()) {
4458 TClingClassInfo cl(fInterpreter,scopename.c_str());
4459 d = cl.GetDataMember(dataname.c_str());
4460 }
4461 else {
4463 d = gcl.GetDataMember(dataname.c_str());
4464 }
4465 return d;
4466}
4467
4468////////////////////////////////////////////////////////////////////////////////
4469/// NOT IMPLEMENTED.
4470
4472{
4473 Error("GetDataMemberWithValue()", "not implemented");
4474 return 0;
4475}
4476
4477////////////////////////////////////////////////////////////////////////////////
4478/// Return pointer to cling DeclId for a data member with a given name.
4479
4481{
4482 // NOT IMPLEMENTED.
4483 Error("GetDataMemberAtAddr()", "not implemented");
4484 return 0;
4485}
4486
4487////////////////////////////////////////////////////////////////////////////////
4488/// Return the cling mangled name for a method of a class with parameters
4489/// params (params is a string of actual arguments, not formal ones). If the
4490/// class is 0 the global function list will be searched.
4491
4492TString TCling::GetMangledName(TClass* cl, const char* method,
4493 const char* params, Bool_t objectIsConst /* = kFALSE */)
4494{
4497 if (cl) {
4498 Long_t offset;
4499 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4500 &offset);
4501 }
4502 else {
4504 Long_t offset;
4505 func.SetFunc(&gcl, method, params, &offset);
4506 }
4508 if (!mi) return "";
4509 TString mangled_name( mi->GetMangledName() );
4510 delete mi;
4511 return mangled_name;
4512}
4513
4514////////////////////////////////////////////////////////////////////////////////
4515/// Return the cling mangled name for a method of a class with a certain
4516/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4517/// list will be searched.
4518
4520 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4521 EFunctionMatchMode mode /* = kConversionMatch */)
4522{
4524 if (cl) {
4525 return ((TClingClassInfo*)cl->GetClassInfo())->
4526 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4527 }
4529 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4530}
4531
4532////////////////////////////////////////////////////////////////////////////////
4533/// Return pointer to cling interface function for a method of a class with
4534/// parameters params (params is a string of actual arguments, not formal
4535/// ones). If the class is 0 the global function list will be searched.
4536
4537void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4538 const char* params, Bool_t objectIsConst /* = kFALSE */)
4539{
4542 if (cl) {
4543 Long_t offset;
4544 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4545 &offset);
4546 }
4547 else {
4549 Long_t offset;
4550 func.SetFunc(&gcl, method, params, &offset);
4551 }
4552 return (void*) func.InterfaceMethod();
4553}
4554
4555////////////////////////////////////////////////////////////////////////////////
4556/// Return pointer to cling interface function for a method of a class with
4557/// a certain name.
4558
4559TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4560{
4562 DeclId_t f;
4563 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4564 if (cl) {
4565 f = cl->GetMethod(method).GetDeclId();
4566 }
4567 else {
4569 f = gcl.GetMethod(method).GetDeclId();
4570 }
4571 return f;
4572
4573}
4574
4575////////////////////////////////////////////////////////////////////////////////
4576/// Insert overloads of name in cl to res.
4577
4578void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
4579 std::vector<DeclId_t>& res) const
4580{
4581 clang::Sema& S = fInterpreter->getSema();
4582 clang::ASTContext& Ctx = S.Context;
4583 const clang::Decl* CtxDecl
4584 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4585 Ctx.getTranslationUnitDecl();
4586 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4587 const clang::DeclContext* DeclCtx = RecDecl;
4588
4589 if (!DeclCtx)
4590 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4591 if (!DeclCtx) return;
4592
4593 clang::DeclarationName DName;
4594 // The DeclarationName is funcname, unless it's a ctor or dtor.
4595 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
4596
4597 if (RecDecl) {
4598 if (RecDecl->getNameAsString() == funcname) {
4599 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4600 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4601 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
4602 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4603 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4604 } else {
4605 DName = &Ctx.Idents.get(funcname);
4606 }
4607 } else {
4608 DName = &Ctx.Idents.get(funcname);
4609 }
4610
4611 clang::LookupResult R(S, DName, clang::SourceLocation(),
4612 Sema::LookupOrdinaryName, clang::Sema::ForRedeclaration);
4613 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
4614 if (R.empty()) return;
4615 R.resolveKind();
4616 res.reserve(res.size() + (R.end() - R.begin()));
4617 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
4618 IR != ER; ++IR) {
4619 if (const clang::FunctionDecl* FD
4620 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
4621 if (!FD->getDescribedFunctionTemplate()) {
4622 res.push_back(FD);
4623 }
4624 }
4625 }
4626}
4627
4628////////////////////////////////////////////////////////////////////////////////
4629/// Return pointer to cling interface function for a method of a class with
4630/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4631/// function list will be searched.
4632
4634 const char* proto,
4635 Bool_t objectIsConst /* = kFALSE */,
4636 EFunctionMatchMode mode /* = kConversionMatch */)
4637{
4639 void* f;
4640 if (cl) {
4641 f = ((TClingClassInfo*)cl->GetClassInfo())->
4642 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4643 }
4644 else {
4646 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4647 }
4648 return f;
4649}
4650
4651////////////////////////////////////////////////////////////////////////////////
4652/// Return pointer to cling DeclId for a method of a class with
4653/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4654/// function list will be searched.
4655
4656TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
4657 const char* params,
4658 Bool_t objectIsConst /* = kFALSE */)
4659{
4661 DeclId_t f;
4662 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4663 if (cl) {
4664 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4665 }
4666 else {
4668 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4669 }
4670 return f;
4671}
4672
4673////////////////////////////////////////////////////////////////////////////////
4674/// Return pointer to cling interface function for a method of a class with
4675/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4676/// function list will be searched.
4677
4678TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
4679 const char* proto,
4680 Bool_t objectIsConst /* = kFALSE */,
4681 EFunctionMatchMode mode /* = kConversionMatch */)
4682{
4684 DeclId_t f;
4685 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4686 if (cl) {
4687 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4688 }
4689 else {
4691 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4692 }
4693 return f;
4694}
4695
4696////////////////////////////////////////////////////////////////////////////////
4697/// Return pointer to cling interface function for a method of a class with
4698/// a certain name.
4699
4700TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
4701{
4703 DeclId_t f;
4704 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4705 if (cl) {
4706 f = cl->GetFunctionTemplate(name);
4707 }
4708 else {
4710 f = gcl.GetFunctionTemplate(name);
4711 }
4712 return f;
4713
4714}
4715
4716////////////////////////////////////////////////////////////////////////////////
4717/// The 'name' is known to the interpreter, this function returns
4718/// the internal version of this name (usually just resolving typedefs)
4719/// This is used in particular to synchronize between the name used
4720/// by rootcling and by the run-time environment (TClass)
4721/// Return 0 if the name is not known.
4722
4723void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
4724{
4725 output.clear();
4726
4728
4730 if (!cl.IsValid()) {
4731 return ;
4732 }
4733 if (full) {
4735 return;
4736 }
4737 // Well well well, for backward compatibility we need to act a bit too
4738 // much like CINT.
4741
4742 return;
4743}
4744
4745////////////////////////////////////////////////////////////////////////////////
4746/// Execute a global function with arguments params.
4747///
4748/// FIXME: The cint-based version of this code does not check if the
4749/// SetFunc() call works, and does not do any real checking
4750/// for errors from the Exec() call. It did fetch the most
4751/// recent cint security error and return that in error, but
4752/// this does not really translate well to cling/clang. We
4753/// should enhance these interfaces so that we can report
4754/// compilation and runtime errors properly.
4755
4756void TCling::Execute(const char* function, const char* params, int* error)
4757{
4759 if (error) {
4760 *error = TInterpreter::kNoError;
4761 }
4763 Long_t offset = 0L;
4765 func.SetFunc(&cl, function, params, &offset);
4766 func.Exec(0);
4767}
4768
4769////////////////////////////////////////////////////////////////////////////////
4770/// Execute a method from class cl with arguments params.
4771///
4772/// FIXME: The cint-based version of this code does not check if the
4773/// SetFunc() call works, and does not do any real checking
4774/// for errors from the Exec() call. It did fetch the most
4775/// recent cint security error and return that in error, but
4776/// this does not really translate well to cling/clang. We
4777/// should enhance these interfaces so that we can report
4778/// compilation and runtime errors properly.
4779
4780void TCling::Execute(TObject* obj, TClass* cl, const char* method,
4781 const char* params, Bool_t objectIsConst, int* error)
4782{
4784 if (error) {
4785 *error = TInterpreter::kNoError;
4786 }
4787 // If the actual class of this object inherits 2nd (or more) from TObject,
4788 // 'obj' is unlikely to be the start of the object (as described by IsA()),
4789 // hence gInterpreter->Execute will improperly correct the offset.
4790 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
4791 Long_t offset = 0L;
4793 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
4794 void* address = (void*)((Long_t)addr + offset);
4795 func.Exec(address);
4796}
4797
4798////////////////////////////////////////////////////////////////////////////////
4799
4800void TCling::Execute(TObject* obj, TClass* cl, const char* method,
4801 const char* params, int* error)
4802{
4803 Execute(obj,cl,method,params,false,error);
4804}
4805
4806////////////////////////////////////////////////////////////////////////////////
4807/// Execute a method from class cl with the arguments in array params
4808/// (params[0] ... params[n] = array of TObjString parameters).
4809/// Convert the TObjArray array of TObjString parameters to a character
4810/// string of comma separated parameters.
4811/// The parameters of type 'char' are enclosed in double quotes and all
4812/// internal quotes are escaped.
4813
4814void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
4815 TObjArray* params, int* error)
4816{
4817 if (!method) {
4818 Error("Execute", "No method was defined");
4819 return;
4820 }
4821 TList* argList = method->GetListOfMethodArgs();
4822 // Check number of actual parameters against of expected formal ones
4823
4824 Int_t nparms = argList->LastIndex() + 1;
4825 Int_t argc = params ? params->GetEntries() : 0;
4826
4827 if (argc > nparms) {
4828 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
4829 return;
4830 }
4831 if (nparms != argc) {
4832 // Let's see if the 'missing' argument are all defaulted.
4833 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
4834 assert(nparms > 0);
4835
4836 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
4837 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
4838 // There is a default value for the first missing
4839 // argument, so we are fine.
4840 } else {
4841 Int_t firstDefault = -1;
4842 for (Int_t i = 0; i < nparms; i ++) {
4843 arg = (TMethodArg *) argList->At( i );
4844 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
4845 firstDefault = i;
4846 break;
4847 }
4848 }
4849 if (firstDefault >= 0) {
4850 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);
4851 } else {
4852 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
4853 }
4854 return;
4855 }
4856 }
4857
4858 const char* listpar = "";
4859 TString complete(10);
4860 if (params) {
4861 // Create a character string of parameters from TObjArray
4862 TIter next(params);
4863 for (Int_t i = 0; i < argc; i ++) {
4864 TMethodArg* arg = (TMethodArg*) argList->At(i);
4866 TObjString* nxtpar = (TObjString*) next();
4867 if (i) {
4868 complete += ',';
4869 }
4870 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
4871 TString chpar('\"');
4872 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
4873 // At this point we have to check if string contains \\"
4874 // and apply some more sophisticated parser. Not implemented yet!
4875 complete += chpar;
4876 complete += '\"';
4877 }
4878 else {
4879 complete += nxtpar->String();
4880 }
4881 }
4882 listpar = complete.Data();
4883 }
4884
4885 // And now execute it.
4887 if (error) {
4888 *error = TInterpreter::kNoError;
4889 }
4890 // If the actual class of this object inherits 2nd (or more) from TObject,
4891 // 'obj' is unlikely to be the start of the object (as described by IsA()),
4892 // hence gInterpreter->Execute will improperly correct the offset.
4893 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
4895 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
4896 func.Init(*minfo);
4897 func.SetArgs(listpar);
4898 // Now calculate the 'this' pointer offset for the method
4899 // when starting from the class described by cl.
4900 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetMethodDecl());
4901 Long_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
4902 void* address = (void*)((Long_t)addr + offset);
4903 func.Exec(address);
4904}
4905
4906////////////////////////////////////////////////////////////////////////////////
4907
4908void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
4909 const void* args[] /*=0*/,
4910 int nargs /*=0*/,
4911 void* ret/*= 0*/) const
4912{
4913 if (!method) {
4914 Error("ExecuteWithArgsAndReturn", "No method was defined");
4915 return;
4916 }
4917
4918 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
4919 TClingCallFunc func(*minfo,*fNormalizedCtxt);
4920 func.ExecWithArgsAndReturn(address, args, nargs, ret);
4921}
4922
4923////////////////////////////////////////////////////////////////////////////////
4924/// Execute a cling macro.
4925
4926Long_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
4927{
4929 fCurExecutingMacros.push_back(filename);
4930 Long_t result = TApplication::ExecuteFile(filename, (int*)error);
4931 fCurExecutingMacros.pop_back();
4932 return result;
4933}
4934
4935////////////////////////////////////////////////////////////////////////////////
4936/// Return the file name of the current un-included interpreted file.
4937/// See the documentation for GetCurrentMacroName().
4938
4940{
4941 Warning("GetTopLevelMacroName", "Must change return type!");
4942 return fCurExecutingMacros.back();
4943}
4944
4945////////////////////////////////////////////////////////////////////////////////
4946/// Return the file name of the currently interpreted file,
4947/// included or not. Example to illustrate the difference between
4948/// GetCurrentMacroName() and GetTopLevelMacroName():
4949/// ~~~ {.cpp}
4950/// void inclfile() {
4951/// std::cout << "In inclfile.C" << std::endl;
4952/// std::cout << " TCling::GetCurrentMacroName() returns " <<
4953/// TCling::GetCurrentMacroName() << std::endl;
4954/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
4955/// TCling::GetTopLevelMacroName() << std::endl;
4956/// }
4957/// ~~~
4958/// ~~~ {.cpp}
4959/// void mymacro() {
4960/// std::cout << "In mymacro.C" << std::endl;
4961/// std::cout << " TCling::GetCurrentMacroName() returns " <<
4962/// TCling::GetCurrentMacroName() << std::endl;
4963/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
4964/// TCling::GetTopLevelMacroName() << std::endl;
4965/// std::cout << " Now calling inclfile..." << std::endl;
4966/// gInterpreter->ProcessLine(".x inclfile.C");;
4967/// }
4968/// ~~~
4969/// Running mymacro.C will print:
4970///
4971/// ~~~ {.cpp}
4972/// root [0] .x mymacro.C
4973/// ~~~
4974/// In mymacro.C
4975/// ~~~ {.cpp}
4976/// TCling::GetCurrentMacroName() returns ./mymacro.C
4977/// TCling::GetTopLevelMacroName() returns ./mymacro.C
4978/// ~~~
4979/// Now calling inclfile...
4980/// In inclfile.h
4981/// ~~~ {.cpp}
4982/// TCling::GetCurrentMacroName() returns inclfile.C
4983/// TCling::GetTopLevelMacroName() returns ./mymacro.C
4984/// ~~~
4985
4987{
4988#if defined(R__MUST_REVISIT)
4989#if R__MUST_REVISIT(6,0)
4990 Warning("GetCurrentMacroName", "Must change return type!");
4991#endif
4992#endif
4993 return fCurExecutingMacros.back();
4994}
4995
4996////////////////////////////////////////////////////////////////////////////////
4997/// Return the absolute type of typeDesc.
4998/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
4999/// You need to use the result immediately before it is being overwritten.
5000
5001const char* TCling::TypeName(const char* typeDesc)
5002{
5003 TTHREAD_TLS(char*) t = 0;
5004 TTHREAD_TLS(unsigned int) tlen = 0;
5005
5006 unsigned int dlen = strlen(typeDesc);
5007 if (dlen > tlen) {
5008 delete[] t;
5009 t = new char[dlen + 1];
5010 tlen = dlen;
5011 }
5012 const char* s, *template_start;
5013 if (!strstr(typeDesc, "(*)(")) {
5014 s = strchr(typeDesc, ' ');
5015 template_start = strchr(typeDesc, '<');
5016 if (!strcmp(typeDesc, "long long")) {
5017 strlcpy(t, typeDesc, dlen + 1);
5018 }
5019 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5020 strlcpy(t, typeDesc, dlen + 1);
5021 }
5022 // s is the position of the second 'word' (if any)
5023 // except in the case of templates where there will be a space
5024 // just before any closing '>': eg.
5025 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5026 else if (s && (template_start == 0 || (s < template_start))) {
5027 strlcpy(t, s + 1, dlen + 1);
5028 }
5029 else {
5030 strlcpy(t, typeDesc, dlen + 1);
5031 }
5032 }
5033 else {
5034 strlcpy(t, typeDesc, dlen + 1);
5035 }
5036 int l = strlen(t);
5037 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&')) {
5038 t[--l] = 0;
5039 }
5040 return t;
5041}
5042
5043static bool requiresRootMap(const char* rootmapfile, cling::Interpreter* interp)
5044{
5045 if (!rootmapfile || !*rootmapfile)
5046 return true;
5047
5048 llvm::StringRef moduleName = llvm::sys::path::filename(rootmapfile);
5049 moduleName.consume_front("lib");
5050 moduleName.consume_back(".rootmap");
5051
5052 Module *M = interp->getCI()->getPreprocessor().getHeaderSearchInfo().lookupModule(moduleName);
5053
5054 return !(M && interp->getSema().isModuleVisible(M));
5055}
5056
5057////////////////////////////////////////////////////////////////////////////////
5058/// Read and parse a rootmapfile in its new format, and return 0 in case of
5059/// success, -1 if the file has already been read, and -3 in case its format
5060/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5061/// error.
5062
5063int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5064{
5065 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5066 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5067
5068 if (rootmapfile && *rootmapfile) {
5069 std::string rootmapfileNoBackslash(rootmapfile);
5070#ifdef _MSC_VER
5071 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5072#endif
5073 // Add content of a specific rootmap file
5074 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5075 return -1;
5076
5077 if (uniqueString)
5078 uniqueString->Append(std::string("\n#line 1 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n");
5079
5080 std::ifstream file(rootmapfileNoBackslash);
5081 std::string line; line.reserve(200);
5082 std::string lib_name; line.reserve(100);
5083 bool newFormat=false;
5084 while (getline(file, line, '\n')) {
5085 if (!newFormat &&
5086 (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5087 file.close();
5088 return -3; // old format
5089 }
5090 newFormat=true;
5091
5092 if (line.compare(0, 9, "{ decls }") == 0 && requiresRootMap(rootmapfile, fInterpreter)) {
5093 // forward declarations
5094
5095 while (getline(file, line, '\n')) {
5096 if (line[0] == '[') break;
5097 if (!uniqueString) {
5098 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5099 rootmapfileNoBackslash.c_str());
5100 return -4;
5101 }
5102 uniqueString->Append(line);
5103 }
5104 }
5105 const char firstChar=line[0];
5106 if (firstChar == '[') {
5107 // new section (library)
5108 auto brpos = line.find(']');
5109 if (brpos == string::npos) continue;
5110 lib_name = line.substr(1, brpos-1);
5111 size_t nspaces = 0;
5112 while( lib_name[nspaces] == ' ' ) ++nspaces;
5113 if (nspaces) lib_name.replace(0, nspaces, "");
5114 if (gDebug > 3) {
5115 TString lib_nameTstr(lib_name.c_str());
5116 TObjArray* tokens = lib_nameTstr.Tokenize(" ");
5117 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5118 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5119 if (wlib) {
5120 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5121 }
5122 else {
5123 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5124 }
5125 delete[] wlib;
5126 delete tokens;
5127 }
5128 }
5129 else {
5130 auto keyLenIt = keyLenMap.find(firstChar);
5131 if (keyLenIt == keyLenMap.end()) continue;
5132 unsigned int keyLen = keyLenIt->second;
5133 // Do not make a copy, just start after the key
5134 const char *keyname = line.c_str()+keyLen;
5135 if (gDebug > 6)
5136 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5137 TEnvRec* isThere = fMapfile->Lookup(keyname);
5138 if (isThere){
5139 if(lib_name != isThere->GetValue()){ // the same key for two different libs
5140 if (firstChar == 'n') {
5141 if (gDebug > 3)
5142 Info("ReadRootmapFile", "namespace %s found in %s is already in %s",
5143 keyname, lib_name.c_str(), isThere->GetValue());
5144 } else if (firstChar == 'h'){ // it is a header: add the libname to the list of libs to be loaded.
5145 lib_name+=" ";
5146 lib_name+=isThere->GetValue();
5147 fMapfile->SetValue(keyname, lib_name.c_str());
5148 }
5149 else if (!TClassEdit::IsSTLCont(keyname)) {
5150 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5151 keyname, lib_name.c_str(), isThere->GetValue());
5152 }
5153 } else { // the same key for the same lib
5154 if (gDebug > 3)
5155 Info("ReadRootmapFile","Key %s was already defined for %s", keyname, lib_name.c_str());
5156 }
5157
5158 } else {
5159 fMapfile->SetValue(keyname, lib_name.c_str());
5160 }
5161 }
5162 }
5163 file.close();
5164 }
5165
5166 return 0;
5167}
5168
5169////////////////////////////////////////////////////////////////////////////////
5170/// Create a resource table and read the (possibly) three resource files, i.e
5171/// $ROOTSYS/etc/system<name> (or ROOTETCDIR/system<name>), $HOME/<name> and
5172/// ./<name>. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You can
5173/// read additional user defined resource files by creating additional TEnv
5174/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5175/// the $HOME/<name> resource file will be skipped. This might be useful in
5176/// case the home directory resides on an automounted remote file system
5177/// and one wants to avoid the file system from being mounted.
5178
5180{
5182
5184
5185 TString sname = "system";
5186 sname += name;
5187 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5188
5189 Int_t ret = ReadRootmapFile(s);
5190 if (ret == -3) // old format
5192 delete [] s;
5193 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5195 ret = ReadRootmapFile(s);
5196 if (ret == -3) // old format
5198 delete [] s;
5199 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5200 ret = ReadRootmapFile(name);
5201 if (ret == -3) // old format
5203 }
5204 } else {
5205 ret = ReadRootmapFile(name);
5206 if (ret == -3) // old format
5208 }
5209 fMapfile->IgnoreDuplicates(ignore);
5210}
5211
5212
5213namespace {
5214 using namespace clang;
5215
5216 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5217 // This class is to be considered an helper for autoloading.
5218 // It is a recursive visitor is used to inspect namespaces coming from
5219 // forward declarations in rootmaps and to set the external visible
5220 // storage flag for them.
5221 public:
5222 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5223 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5224 // We want to enable the external lookup for this namespace
5225 // because it may shadow the lookup of other names contained
5226 // in that namespace
5227
5228 nsDecl->setHasExternalVisibleStorage();
5229 fNSSet.insert(nsDecl);
5230 return true;
5231 }
5232 private:
5233 std::unordered_set<const NamespaceDecl*>& fNSSet;
5234
5235 };
5236}
5237
5238////////////////////////////////////////////////////////////////////////////////
5239/// Load map between class and library. If rootmapfile is specified a
5240/// specific rootmap file can be added (typically used by ACLiC).
5241/// In case of error -1 is returned, 0 otherwise.
5242/// The interpreter uses this information to automatically load the shared
5243/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5244
5245Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5246{
5248 // open the [system].rootmap files
5249 if (!fMapfile) {
5250 fMapfile = new TEnv();
5252// fMapNamespaces = new THashTable();
5253// fMapNamespaces->SetOwner();
5256 InitRootmapFile(".rootmap");
5257 }
5258 bool needsRootMap = true;
5259 if (rootmapfile && *rootmapfile)
5260 needsRootMap = requiresRootMap(rootmapfile, fInterpreter);
5261
5262 // Prepare a list of all forward declarations for cling
5263 // For some experiments it is easily as big as 500k characters. To be on the
5264 // safe side, we go for 1M.
5265 TUniqueString uniqueString(1048576);
5266
5267 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5268 // A rootmap file must end with the string ".rootmap".
5269 TString ldpath = gSystem->GetDynamicPath();
5270 if (ldpath != fRootmapLoadPath) {
5271 fRootmapLoadPath = ldpath;
5272#ifdef WIN32
5273 TObjArray* paths = ldpath.Tokenize(";");
5274#else
5275 TObjArray* paths = ldpath.Tokenize(":");
5276#endif
5277 TString d;
5278 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5279 d = ((TObjString *)paths->At(i))->GetString();
5280 // check if directory already scanned
5281 Int_t skip = 0;
5282 for (Int_t j = 0; j < i; j++) {
5283 TString pd = ((TObjString *)paths->At(j))->GetString();
5284 if (pd == d) {
5285 skip++;
5286 break;
5287 }
5288 }
5289 if (!skip) {
5290 void* dirp = gSystem->OpenDirectory(d);
5291 if (dirp) {
5292 if (gDebug > 3) {
5293 Info("LoadLibraryMap", "%s", d.Data());
5294 }
5295 const char* f1;
5296 while ((f1 = gSystem->GetDirEntry(dirp))) {
5297 TString f = f1;
5298 if (f.EndsWith(".rootmap")) {
5299 TString p;
5300 p = d + "/" + f;
5302 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5303 if (gDebug > 4) {
5304 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5305 }
5306 Int_t ret;
5307 if (needsRootMap)
5308 ret = ReadRootmapFile(p,&uniqueString);
5309 else
5310 ret = ReadRootmapFile(p);
5311
5312 if (ret == 0)
5314 if (ret == -3) {
5315 // old format
5317 fRootmapFiles->Add(new TNamed(f, p));
5318 }
5319 }
5320 // else {
5321 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5322 // fRootmapFiles->FindObject(f)->ls();
5323 // }
5324 }
5325 }
5326 if (f.BeginsWith("rootmap")) {
5327 TString p;
5328 p = d + "/" + f;
5329 FileStat_t stat;
5330 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5331 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5332 }
5333 }
5334 }
5335 }
5336 gSystem->FreeDirectory(dirp);
5337 }
5338 }
5339 delete paths;
5340 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5341 return -1;
5342 }
5343 }
5344 if (rootmapfile && *rootmapfile) {
5345 Int_t res;
5346 if (needsRootMap)
5347 res = ReadRootmapFile(rootmapfile, &uniqueString);
5348 else
5349 res = ReadRootmapFile(rootmapfile);
5350 if (res == 0) {
5351 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5352 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5353 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5354 }
5355 else if (res == -3) {
5356 // old format
5358 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5359 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5360 fMapfile->IgnoreDuplicates(ignore);
5361 }
5362 }
5363 TEnvRec* rec;
5364 TIter next(fMapfile->GetTable());
5365 while ((rec = (TEnvRec*) next())) {
5366 TString cls = rec->GetName();
5367 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5368 // get the first lib from the list of lib and dependent libs
5369 TString libs = rec->GetValue();
5370 if (libs == "") {
5371 continue;
5372 }
5373 TString delim(" ");
5374 TObjArray* tokens = libs.Tokenize(delim);
5375 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5376 // convert "@@" to "::", we used "@@" because TEnv
5377 // considers "::" a terminator
5378 cls.Remove(0, 8);
5379 cls.ReplaceAll("@@", "::");
5380 // convert "-" to " ", since class names may have
5381 // blanks and TEnv considers a blank a terminator
5382 cls.ReplaceAll("-", " ");
5383 if (gDebug > 6) {
5384 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5385 if (wlib) {
5386 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5387 }
5388 else {
5389 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5390 }
5391 delete[] wlib;
5392 }
5393 // Fill in the namespace candidate list
5394// Ssiz_t last = cls.Last(':');
5395// if (last != kNPOS) {
5396// // Please note that the funny op overload does substring.
5397// TString namespaceCand = cls(0, last - 1);
5398// // This is a reference to a substring that lives in fMapfile
5399// if (!fMapNamespaces->FindObject(namespaceCand.Data()))
5400// fMapNamespaces->Add(new TNamed(namespaceCand.Data(), ""));
5401// }
5402 delete tokens;
5403 }
5404 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5405 cls.Remove(0, 8);
5406 // convert "-" to " ", since class names may have
5407 // blanks and TEnv considers a blank a terminator
5408 cls.ReplaceAll("-", " ");
5409 fInterpreter->declare(cls.Data());
5410 }
5411 }
5412
5413 // Process the forward declarations collected
5414 cling::Transaction* T = nullptr;
5415 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5416 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5417
5418 if (compRes!=cling::Interpreter::kSuccess){
5419 Warning("LoadLibraryMap",
5420 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5421 }
5422
5423 if (T){
5424 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5425 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5426 if (declIt->m_DGR.isSingleDecl()) {
5427 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5428 if (NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
5429 evsAdder.TraverseDecl(NSD);
5430 }
5431 }
5432 }
5433 }
5434 }
5435
5436 // clear duplicates
5437
5438 return 0;
5439}
5440
5441////////////////////////////////////////////////////////////////////////////////
5442/// Scan again along the dynamic path for library maps. Entries for the loaded
5443/// shared libraries are unloaded first. This can be useful after reseting
5444/// the dynamic path through TSystem::SetDynamicPath()
5445/// In case of error -1 is returned, 0 otherwise.
5446
5448{
5451 return 0;
5452}
5453
5454////////////////////////////////////////////////////////////////////////////////
5455/// Reload the library map entries coming from all the loaded shared libraries,
5456/// after first unloading the current ones.
5457/// In case of error -1 is returned, 0 otherwise.
5458
5460{
5461 const TString sharedLibLStr = GetSharedLibs();
5462 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5463 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5464 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5465 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5466 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5467 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5468 if (ret < 0) {
5469 continue;
5470 }
5471 TString rootMapBaseStr = sharedLibBaseStr;
5472 if (sharedLibBaseStr.EndsWith(".dll")) {
5473 rootMapBaseStr.ReplaceAll(".dll", "");
5474 }
5475 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5476 rootMapBaseStr.ReplaceAll(".DLL", "");
5477 }
5478 else if (sharedLibBaseStr.EndsWith(".so")) {
5479 rootMapBaseStr.ReplaceAll(".so", "");
5480 }
5481 else if (sharedLibBaseStr.EndsWith(".sl")) {
5482 rootMapBaseStr.ReplaceAll(".sl", "");
5483 }
5484 else if (sharedLibBaseStr.EndsWith(".dl")) {
5485 rootMapBaseStr.ReplaceAll(".dl", "");
5486 }
5487 else if (sharedLibBaseStr.EndsWith(".a")) {
5488 rootMapBaseStr.ReplaceAll(".a", "");
5489 }
5490 else {
5491 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5492 delete sharedLibL;
5493 return -1;
5494 }
5495 rootMapBaseStr += ".rootmap";
5496 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5497 if (!rootMap) {
5498 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5499 delete[] rootMap;
5500 delete sharedLibL;
5501 return -1;
5502 }
5503 const Int_t status = LoadLibraryMap(rootMap);
5504 if (status < 0) {
5505 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5506 delete[] rootMap;
5507 delete sharedLibL;
5508 return -1;
5509 }
5510 delete[] rootMap;
5511 }
5512 delete sharedLibL;
5513 return 0;
5514}
5515
5516////////////////////////////////////////////////////////////////////////////////
5517/// Unload the library map entries coming from all the loaded shared libraries.
5518/// Returns 0 if succesful
5519
5521{
5522 const TString sharedLibLStr = GetSharedLibs();
5523 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5524 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5525 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5526 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5527 UnloadLibraryMap(sharedLibBaseStr);
5528 }
5529 delete sharedLibL;
5530 return 0;
5531}
5532
5533////////////////////////////////////////////////////////////////////////////////
5534/// Unload library map entries coming from the specified library.
5535/// Returns -1 in case no entries for the specified library were found,
5536/// 0 otherwise.
5537
5539{
5540 if (!fMapfile || !library || !*library) {
5541 return 0;
5542 }
5543 TString libname(library);
5544 Ssiz_t idx = libname.Last('.');
5545 if (idx != kNPOS) {
5546 libname.Remove(idx);
5547 }
5548 size_t len = libname.Length();
5549 TEnvRec *rec;
5550 TIter next(fMapfile->GetTable());
5552 Int_t ret = 0;
5553 while ((rec = (TEnvRec *) next())) {
5554 TString cls = rec->GetName();
5555 if (cls.Length() > 2) {
5556 // get the first lib from the list of lib and dependent libs
5557 TString libs = rec->GetValue();
5558 if (libs == "") {
5559 continue;
5560 }
5561 TString delim(" ");
5562 TObjArray* tokens = libs.Tokenize(delim);
5563 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5564 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5565 // convert "@@" to "::", we used "@@" because TEnv
5566 // considers "::" a terminator
5567 cls.Remove(0, 8);
5568 cls.ReplaceAll("@@", "::");
5569 // convert "-" to " ", since class names may have
5570 // blanks and TEnv considers a blank a terminator
5571 cls.ReplaceAll("-", " ");
5572 }
5573 if (!strncmp(lib, libname.Data(), len)) {
5574 if (fMapfile->GetTable()->Remove(rec) == 0) {
5575 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
5576 ret = -1;
5577 }
5578 }
5579 delete tokens;
5580 }
5581 }
5582 if (ret >= 0) {
5583 TString library_rootmap(library);
5584 if (!library_rootmap.EndsWith(".rootmap"))
5585 library_rootmap.Append(".rootmap");
5586 TNamed* mfile = 0;
5587 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5588 fRootmapFiles->Remove(mfile);
5589 delete mfile;
5590 }
5592 }
5593 return ret;
5594}
5595
5596////////////////////////////////////////////////////////////////////////////////
5597/// Register the autoloading information for a class.
5598/// libs is a space separated list of libraries.
5599
5600Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
5601{
5602 if (!cls || !*cls)
5603 return 0;
5604
5605 TString key = TString("Library.") + cls;
5606 // convert "::" to "@@", we used "@@" because TEnv
5607 // considers "::" a terminator
5608 key.ReplaceAll("::", "@@");
5609 // convert "-" to " ", since class names may have
5610 // blanks and TEnv considers a blank a terminator
5611 key.ReplaceAll(" ", "-");
5612
5614 if (!fMapfile) {
5615 fMapfile = new TEnv();
5617// fMapNamespaces = new THashTable();
5618// fMapNamespaces->SetOwner();
5619
5622
5623 InitRootmapFile(".rootmap");
5624 }
5625 //fMapfile->SetValue(key, libs);
5626 fMapfile->SetValue(cls, libs);
5627 return 1;
5628}
5629
5630////////////////////////////////////////////////////////////////////////////////
5631/// Demangle the name (from the typeinfo) and then request the class
5632/// via the usual name based interface (TClass::GetClass).
5633
5634TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
5635{
5636 int err = 0;
5637 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
5638 if (err) return 0;
5639 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
5640 free(demangled_name);
5641 return theClass;
5642}
5643
5644////////////////////////////////////////////////////////////////////////////////
5645/// Load library containing the specified class. Returns 0 in case of error
5646/// and 1 in case if success.
5647
5648Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
5649{
5650 int err = 0;
5651 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
5652 if (err) {
5653 return 0;
5654 }
5655
5656 std::string demangled_name(demangled_name_c);
5657 free(demangled_name_c);
5658
5659 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
5660 // shortened name.
5662 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
5663
5664 // No need to worry about typedef, they aren't any ... but there are
5665 // inlined namespaces ...
5666
5667 Int_t result = AutoLoad(demangled_name.c_str());
5668 if (result == 0) {
5669 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
5670 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
5671 }
5672
5673 return result;
5674}
5675
5676////////////////////////////////////////////////////////////////////////////////
5677/// Load library containing the specified class. Returns 0 in case of error
5678/// and 1 in case if success.
5679
5680Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
5681{
5683
5684 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
5685 // The library is already loaded as the class's dictionary is known.
5686 // Return success.
5687 // Note: the name (cls) is expected to be normalized as it comes either
5688 // from a callbacks (that can/should calculate the normalized name from the
5689 // decl) or from TClass::GetClass (which does also calculate the normalized
5690 // name).
5691 return 1;
5692 }
5693
5694 if (gDebug > 2) {
5695 Info("TCling::AutoLoad",
5696 "Trying to autoload for %s", cls);
5697 }
5698
5699 Int_t status = 0;
5700 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
5701 if (gDebug > 2) {
5702 Info("TCling::AutoLoad",
5703 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
5704 }
5705 return status;
5706 }
5707 if (!fAllowLibLoad) {
5708 // Never load any library from rootcling/genreflex.
5709 if (gDebug > 2) {
5710 Info("TCling::AutoLoad",
5711 "Explicitly disabled (the class name is %s)", cls);
5712 }
5713 return 0;
5714 }
5715 // Prevent the recursion when the library dictionary are loaded.
5716 SuspendAutoloadingRAII autoLoadOff(this);
5717 // Try using externally provided callback first.
5718 if (fAutoLoadCallBack) {
5719 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
5720 if (success)
5721 return success;
5722 }
5723 // lookup class to find list of dependent libraries
5724 TString deplibs = GetClassSharedLibs(cls);
5725 if (!deplibs.IsNull()) {
5726 TString delim(" ");
5727 TObjArray* tokens = deplibs.Tokenize(delim);
5728 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
5729 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
5730 if (gROOT->LoadClass(cls, deplib) == 0) {
5731 if (gDebug > 0) {
5732 Info("TCling::AutoLoad",
5733 "loaded dependent library %s for %s", deplib, cls);
5734 }
5735 }
5736 else {
5737 Error("TCling::AutoLoad",
5738 "failure loading dependent library %s for %s",
5739 deplib, cls);
5740 }
5741 }
5742 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5743 if (lib && lib[0]) {
5744 if (gROOT->LoadClass(cls, lib) == 0) {
5745 if (gDebug > 0) {
5746 Info("TCling::AutoLoad",
5747 "loaded library %s for %s", lib, cls);
5748 }
5749 status = 1;
5750 }
5751 else {
5752 Error("TCling::AutoLoad",
5753 "failure loading library %s for %s", lib, cls);
5754 }
5755 }
5756 delete tokens;
5757 }
5758
5759 return status;
5760}
5761
5762////////////////////////////////////////////////////////////////////////////////
5763/// Parse the payload or header.
5764
5765static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
5766 Bool_t header,
5767 cling::Interpreter *interpreter)
5768{
5769 std::string code = gNonInterpreterClassDef ;
5770 if (!header) {
5771 // This is the complete header file content and not the
5772 // name of a header.
5773 code += what;
5774
5775 } else {
5776 code += ("#include \"");
5777 code += what;
5778 code += "\"\n";
5779 }
5780 code += ("#ifdef __ROOTCLING__\n"
5781 "#undef __ROOTCLING__\n"
5782 + gInterpreterClassDef +
5783 "#endif");
5784
5785 cling::Interpreter::CompilationResult cr;
5786 {
5787 // scope within which diagnostics are de-activated
5788 // For now we disable diagnostics because we saw them already at
5789 // dictionary generation time. That won't be an issue with the PCMs.
5790
5791 Sema &SemaR = interpreter->getSema();
5792 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
5793 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
5794
5795 #if defined(R__MUST_REVISIT)
5796 #if R__MUST_REVISIT(6,2)
5797 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
5798 #endif
5799 #endif
5800
5801 cr = interpreter->parseForModule(code);
5802 }
5803 return cr;
5804}
5805
5806////////////////////////////////////////////////////////////////////////////////
5807/// Helper routine for TCling::AutoParse implementing the actual call to the
5808/// parser and looping over template parameters (if
5809/// any) and when they don't have a registered header to autoparse,
5810/// recurse over their template parameters.
5811///
5812/// Returns the number of header parsed.
5813
5814UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
5815{
5816 // We assume the lock has already been taken.
5817 // R__LOCKGUARD(gInterpreterMutex);
5818
5819 Int_t nHheadersParsed = 0;
5820 unsigned long offset = 0;
5821 if (strncmp(cls, "const ", 6) == 0) {
5822 offset = 6;
5823 }
5824
5825 // Loop on the possible autoparse keys
5826 bool skipFirstEntry = false;
5827 std::vector<std::string> autoparseKeys;
5828 if (strchr(cls, '<')) {
5829 int nestedLoc = 0;
5830 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
5831 // Check if we can skip the name of the template in the autoparses
5832 // Take all the scopes one by one. If all of them are in the AST, we do not
5833 // need to autoparse for that particular template.
5834 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
5835 // autoparseKeys[0] is empty when the input is not a template instance.
5836 // The case strchr(cls, '<') != 0 but still not a template instance can
5837 // happens 'just' for string (GetSplit replaces the template by the short name
5838 // and then use that for thew splitting)
5839 TString templateName(autoparseKeys[0]);
5840 auto tokens = templateName.Tokenize("::");
5841 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
5842 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
5843 if (TClassEdit::IsStdClass(cls + offset))
5844 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
5845 auto nTokens = tokens->GetEntries();
5846 for (Int_t tk = 0; tk < nTokens; ++tk) {
5847 auto scopeObj = tokens->UncheckedAt(tk);
5848 auto scopeName = ((TObjString*) scopeObj)->String().Data();
5849 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
5850 // Check if we have multiple nodes in the AST with this name
5851 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
5852 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
5853 if (!previousScopeAsContext) break; // this is not a context
5854 }
5855 delete tokens;
5856 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
5857 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
5858 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
5859 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
5860 skipFirstEntry = templatedDecl->hasDefinition();
5861 }
5862 }
5863 }
5864
5865 }
5866 }
5867 if (topLevel) autoparseKeys.emplace_back(cls);
5868
5869 for (const auto & apKeyStr : autoparseKeys) {
5870 if (skipFirstEntry) {
5871 skipFirstEntry=false;
5872 continue;
5873 }
5874 if (apKeyStr.empty()) continue;
5875 const char *apKey = apKeyStr.c_str();
5876 std::size_t normNameHash(fStringHashFunction(apKey));
5877 // If the class was not looked up
5878 if (gDebug > 1) {
5879 Info("TCling::AutoParse",
5880 "Starting autoparse for %s\n", apKey);
5881 }
5882 if (fLookedUpClasses.insert(normNameHash).second) {
5883 auto const &iter = fClassesHeadersMap.find(normNameHash);
5884 if (iter != fClassesHeadersMap.end()) {
5885 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
5886 fTransactionHeadersMap.insert({T,normNameHash});
5887 auto const &hNamesPtrs = iter->second;
5888 if (gDebug > 1) {
5889 Info("TCling::AutoParse",
5890 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
5891 }
5892 for (auto & hName : hNamesPtrs) {
5893 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
5894 if (0 != fPayloads.count(normNameHash)) {
5895 float initRSSval=0.f, initVSIZEval=0.f;
5896 (void) initRSSval; // Avoid unused var warning
5897 (void) initVSIZEval;
5898 if (gDebug > 0) {
5899 Info("AutoParse",
5900 "Parsing full payload for %s", apKey);
5901 ProcInfo_t info;
5902 gSystem->GetProcInfo(&info);
5903 initRSSval = 1e-3*info.fMemResident;
5904 initVSIZEval = 1e-3*info.fMemVirtual;
5905 }
5906 auto cRes = ExecAutoParse(hName, kFALSE, fInterpreter);
5907 if (cRes != cling::Interpreter::kSuccess) {
5908 if (hName[0] == '\n')
5909 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
5910 } else {
5911 fParsedPayloadsAddresses.insert(hName);
5912 nHheadersParsed++;
5913 if (gDebug > 0){
5914 ProcInfo_t info;
5915 gSystem->GetProcInfo(&info);
5916 float endRSSval = 1e-3*info.fMemResident;
5917 float endVSIZEval = 1e-3*info.fMemVirtual;
5918 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
5919 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
5920 }
5921 }
5922 } else if (!IsLoaded(hName)) {
5923 if (gDebug > 0) {
5924 Info("AutoParse",
5925 "Parsing single header %s", hName);
5926 }
5927 auto cRes = ExecAutoParse(hName, kTRUE, fInterpreter);
5928 if (cRes != cling::Interpreter::kSuccess) {
5929 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
5930 } else {
5931 nHheadersParsed++;
5932 }
5933 }
5934 }
5935 }
5936 else {
5937 // There is no header registered for this class, if this a
5938 // template, it will be instantiated if/when it is requested
5939 // and if we do no load/parse its components we might end up
5940 // not using an eventual specialization.
5941 if (strchr(apKey, '<')) {
5942 nHheadersParsed += AutoParseImplRecurse(apKey, false);
5943 }
5944 }
5945 }
5946 }
5947
5948 return nHheadersParsed;
5949
5950}
5951
5952////////////////////////////////////////////////////////////////////////////////
5953/// Parse the headers relative to the class
5954/// Returns 1 in case of success, 0 in case of failure
5955
5956Int_t TCling::AutoParse(const char *cls)
5957{
5959
5962 return AutoLoad(cls);
5963 } else {
5964 return 0;
5965 }
5966 }
5967
5968 if (gDebug > 1) {
5969 Info("TCling::AutoParse",
5970 "Trying to autoparse for %s", cls);
5971 }
5972
5973 // The catalogue of headers is in the dictionary
5975 && !gClassTable->GetDictNorm(cls)) {
5976 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
5977 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
5978 fInterpreter->getSema());
5979 AutoLoad(cls, true /*knowDictNotLoaded*/);
5980 }
5981
5982 // Prevent the recursion when the library dictionary are loaded.
5983 SuspendAutoloadingRAII autoLoadOff(this);
5984
5985 // No recursive header parsing on demand; we require headers to be standalone.
5986 SuspendAutoParsing autoParseRAII(this);
5987
5988 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
5989
5990 if (nHheadersParsed != 0) {
5991 while (!fClassesToUpdate.empty()) {
5992 TClass *oldcl = fClassesToUpdate.back().first;
5993 if (oldcl->GetState() != TClass::kHasTClassInit) {
5994 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
5995 DictFuncPtr_t dict = fClassesToUpdate.back().second;
5996 fClassesToUpdate.pop_back();
5997 // Calling func could manipulate the list so, let maintain the list
5998 // then call the dictionary function.
5999 TClass *ncl = dict();
6000 if (ncl) ncl->PostLoadCheck();
6001 } else {
6002 fClassesToUpdate.pop_back();
6003 }
6004 }
6005 }
6006
6007 return nHheadersParsed > 0 ? 1 : 0;
6008}
6009
6010// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6011// Try to solve the problem by autoloading. Return true when autoloading success, return
6012// false if not.
6013bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6014{
6015 StringRef errMsg(errmessage);
6016 if (errMsg.contains("undefined symbol: ")) {
6017 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6018 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6019 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6020 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6021 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6022 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6023 return true;
6024 } else {
6025 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6026 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6027 return true;
6028 }
6029
6030 return false;
6031}
6032
6033// This is a GNU implementation of hash used in bloom filter!
6034static uint32_t GNUHash(StringRef S) {
6035 uint32_t H = 5381;
6036 for (uint8_t C : S)
6037 H = (H << 5) + H + C;
6038 return H;
6039}
6040
6041static StringRef GetGnuHashSection(llvm::object::ObjectFile *file) {
6042 for (auto S : file->sections()) {
6043 StringRef name;
6044 S.getName(name);
6045 if (name == ".gnu.hash") {
6046 StringRef content;
6047 S.getContents(content);
6048 return content;
6049 }
6050 }
6051 return "";
6052}
6053
6054// Bloom filter. See https://blogs.oracle.com/solaris/gnu-hash-elf-sections-v2
6055// for detailed desctiption. In short, there is a .gnu.hash section in so files which contains
6056// bloomfilter hash value that we can compare with our mangled_name hash. This is a false positive
6057// probability data structure and enables us to skip libraries which doesn't contain mangled_name definition!
6058// PE and Mach-O files doesn't have .gnu.hash bloomfilter section, so this is a specific optimization for ELF.
6059// This is fine because performance critical part (data centers) are running on Linux :)
6060static bool LookupBloomFilter(llvm::object::ObjectFile *soFile, uint32_t hash) {
6061 const int bits = 64;
6062
6063 StringRef contents = GetGnuHashSection(soFile);
6064 if (contents.size() < 16)
6065 // We need to search if the library doesn't have .gnu.hash section!
6066 return true;
6067 const char* hashContent = contents.data();
6068
6069 // See https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/ for .gnu.hash table layout.
6070 uint32_t maskWords = *reinterpret_cast<const uint32_t *>(hashContent + 8);
6071 uint32_t shift2 = *reinterpret_cast<const uint32_t *>(hashContent + 12);
6072 uint32_t hash2 = hash >> shift2;
6073 uint32_t n = (hash / bits) % maskWords;
6074
6075 const char *bloomfilter = hashContent + 16;
6076 const char *hash_pos = bloomfilter + n*(bits/8); // * (Bits / 8)
6077 uint64_t word = *reinterpret_cast<const uint64_t *>(hash_pos);
6078 uint64_t bitmask = ( (1ULL << (hash % bits)) | (1ULL << (hash2 % bits)));
6079 return (bitmask & word) == bitmask;
6080}
6081
6082// Lookup for normal symbols
6083static bool LookupNormalSymbols(llvm::object::ObjectFile *RealSoFile, const std::string& mangled_name, const std::string& LibName)
6084{
6085 uint32_t hashedMangle = GNUHash(mangled_name);
6086 // Check Bloom filter. If false, it means that this library doesn't contain mangled_name defenition
6087 if (!LookupBloomFilter(RealSoFile, hashedMangle))
6088 return false;
6089
6090 auto Symbols = RealSoFile->symbols();
6091 for (auto S : Symbols) {
6092 uint32_t Flags = S.getFlags();
6093 // DO NOT insert to table if symbol was undefined
6094 if (Flags & llvm::object::SymbolRef::SF_Undefined)
6095 continue;
6096
6097 // Note, we are at last resort and loading library based on a weak
6098 // symbol is allowed. Otherwise, the JIT will issue an unresolved
6099 // symbol error.
6100 //
6101 // There are other weak symbol kinds (marked as 'V') to denote
6102 // typeinfo and vtables. It is unclear whether we should load such
6103 // libraries or from which library we should resolve the symbol.
6104 // We seem to not have a way to differentiate it from the symbol API.
6105
6106 llvm::Expected<StringRef> SymNameErr = S.getName();
6107 if (!SymNameErr) {
6108 Warning("LookupNormalSymbols", "Failed to read symbol");
6109 continue;
6110 }
6111
6112 if (SymNameErr.get() == mangled_name)
6113 return true;
6114 }
6115
6116 return false;
6117}
6118
6119static void* LazyFunctionCreatorAutoloadForModule(const std::string& mangled_name,
6120 cling::Interpreter *fInterpreter) {
6121 using namespace llvm::object;
6122 using namespace llvm::sys::path;
6123 using namespace llvm::sys::fs;
6124
6126
6127 static bool sFirstRun = true;
6128 static bool sFirstSystemLibrary = true;
6129 // sLibraies contains pair of sPaths[i] (eg. /home/foo/module) and library name (eg. libTMVA.so). The
6130 // reason why we're separating sLibraries and sPaths is that we have a lot of
6131 // dupulication in path, for example we have "/home/foo/module-release/lib/libFoo.so", "/home/../libBar.so", "/home/../lib.."
6132 // and it's waste of memory to store the full path.
6133 static std::vector< std::pair<uint32_t, std::string> > sLibraries;
6134 static std::vector<std::string> sPaths;
6135
6136 // For system header autoloading
6137 static std::vector< std::pair<uint32_t, std::string> > sSysLibraries;
6138 static std::vector<std::string> sSysPaths;
6139
6140 if (sFirstRun) {
6141 TCling__FindLoadedLibraries(sLibraries, sPaths, *fInterpreter, /* searchSystem */ false);
6142 sFirstRun = false;
6143 }
6144
6145 // The JIT gives us a mangled name which has only one leading underscore on
6146 // all platforms, for instance _ZN8TRandom34RndmEv. However, on OSX the
6147 // linker stores this symbol as __ZN8TRandom34RndmEv (adding an extra _).
6148#ifdef R__MACOSX
6149 std::string name_in_so = "_" + mangled_name;
6150#else
6151 std::string name_in_so = mangled_name;
6152#endif
6153
6154
6155 // Iterate over files under this path. We want to get each ".so" files
6156 for (std::pair<uint32_t, std::string> &P : sLibraries) {
6157 llvm::SmallString<400> Vec(sPaths[P.first]);
6158 llvm::sys::path::append(Vec, StringRef(P.second));
6159 const std::string LibName = Vec.str();
6160
6161 auto SoFile = ObjectFile::createObjectFile(LibName);
6162 if (!SoFile)
6163 continue;
6164
6165 if (LookupNormalSymbols(SoFile.get().getBinary(), name_in_so, LibName)) {
6166 if (gSystem->Load(LibName.c_str(), "", false) < 0)
6167 Error("LazyFunctionCreatorAutoloadForModule", "Failed to load library %s", LibName.c_str());
6168
6169 // We want to delete a loaded library from sLibraries cache, because sLibraries is
6170 // a vector of candidate libraries which might be loaded in the future.
6171 sLibraries.erase(std::remove(sLibraries.begin(), sLibraries.end(), P), sLibraries.end());
6172 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6173 return addr;
6174 }
6175 }
6176
6177 // Normal lookup failed! Fall back to system library
6178 if (sFirstSystemLibrary) {
6179 TCling__FindLoadedLibraries(sSysLibraries, sSysPaths, *fInterpreter, /* searchSystem */ true);
6180 sFirstSystemLibrary = false;
6181 }
6182
6183 for (std::pair<uint32_t, std::string> &P : sSysLibraries) {
6184 llvm::SmallString<400> Vec(sSysPaths[P.first]);
6185 llvm::sys::path::append(Vec, StringRef(P.second));
6186 const std::string LibName = Vec.str();
6187
6188 auto SoFile = ObjectFile::createObjectFile(LibName);
6189 if (!SoFile)
6190 continue;
6191
6192 auto RealSoFile = SoFile.get().getBinary();
6193
6194 if (LookupNormalSymbols(RealSoFile, name_in_so, LibName)) {
6195 if (gSystem->Load(LibName.c_str(), "", false) < 0)
6196 Error("LazyFunctionCreatorAutoloadForModule", "Failed to load library %s", LibName.c_str());
6197
6198 sSysLibraries.erase(std::remove(sSysLibraries.begin(), sSysLibraries.end(), P), sSysLibraries.end());
6199 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6200 return addr;
6201 }
6202
6203 // Lookup for dynamic symbols
6204 auto sections = RealSoFile->sections();
6205 for (auto section : sections) {
6206 llvm::StringRef sectionName;
6207 section.getName(sectionName);
6208
6209 // .dynstr contains string of dynamic symbols
6210 if (sectionName == ".dynstr") {
6211 llvm::StringRef dContents;
6212 section.getContents(dContents);
6213 // If this library contains mangled name
6214 if (dContents.contains(mangled_name)) {
6215 if (gSystem->Load(LibName.c_str(), "", false) < 0)
6216 Error("LazyFunctionCreatorAutoloadForModule", "Failed to load library %s", LibName.c_str());
6217
6218 // Delete a loaded library from sLibraries cache.
6219 sSysLibraries.erase(std::remove(sSysLibraries.begin(), sSysLibraries.end(), P), sSysLibraries.end());
6220 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6221 return addr;
6222 }
6223 }
6224 }
6225 }
6226
6227 // Lookup failed!!!!
6228 return nullptr;
6229}
6230
6231////////////////////////////////////////////////////////////////////////////////
6232/// Autoload a library based on a missing symbol.
6233
6234void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6237
6238 // First see whether the symbol is in the library that we are currently
6239 // loading. It will have access to the symbols of its dependent libraries,
6240 // thus checking "back()" is sufficient.
6241 if (!fRegisterModuleDyLibs.empty()) {
6242 if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
6243 mangled_name.c_str())) {
6244 return addr;
6245 }
6246 }
6247
6248 int err = 0;
6249 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6250 if (err) {
6251 return 0;
6252 }
6253
6254 std::string name(demangled_name_c);
6255 free(demangled_name_c);
6256
6257 //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
6258 //
6259 // Separate out the class or namespace part of the
6260 // function name.
6261 //
6262
6263 std::string::size_type pos = name.find("__thiscall ");
6264 if (pos != std::string::npos) {
6265 name.erase(0, pos + sizeof("__thiscall ")-1);
6266 }
6267 pos = name.find("__cdecl ");
6268 if (pos != std::string::npos) {
6269 name.erase(0, pos + sizeof("__cdecl ")-1);
6270 }
6271 if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
6272 name.erase(0, sizeof("typeinfo for ")-1);
6273 } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
6274 name.erase(0, sizeof("vtable for ")-1);
6275 } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
6276 && !isalnum(name[sizeof("operator")])) {
6277 // operator...(A, B) - let's try with A!
6278 name.erase(0, sizeof("operator")-1);
6279 pos = name.rfind('(');
6280 if (pos != std::string::npos) {
6281 name.erase(0, pos + 1);
6282 pos = name.find(",");
6283 if (pos != std::string::npos) {
6284 // remove next arg up to end, leaving only the first argument type.
6285 name.erase(pos);
6286 }
6287 pos = name.rfind(" const");
6288 if (pos != std::string::npos) {
6289 name.erase(pos, strlen(" const"));
6290 }
6291 while (!name.empty() && strchr("&*", name.back()))
6292 name.erase(name.length() - 1);
6293 }
6294 } else {
6297 name = fsi.fScopeName;
6298 }
6299 //fprintf(stderr, "name: '%s'\n", name.c_str());
6300 // Now we have the class or namespace name, so do the lookup.
6301 TString libs = GetClassSharedLibs(name.c_str());
6302 if (libs.IsNull()) {
6303 // Not found in the map, all done.
6304 return 0;
6305 }
6306 //fprintf(stderr, "library: %s\n", iter->second.c_str());
6307 // Now we have the name of the libraries to load, so load them.
6308
6309 TString lib;
6310 Ssiz_t posLib = 0;
6311 while (libs.Tokenize(lib, posLib)) {
6312 if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
6313 // The library load failed, all done.
6314 //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
6315 return 0;
6316 }
6317 }
6318
6319 //fprintf(stderr, "load succeeded.\n");
6320 // Get the address of the function being called.
6321 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6322 //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
6323 return addr;
6324}
6325
6326////////////////////////////////////////////////////////////////////////////////
6327
6329{
6330// if (fMapNamespaces){
6331// return fMapNamespaces->FindObject(name);
6332// }
6333 return false;
6334}
6335
6336////////////////////////////////////////////////////////////////////////////////
6337
6338Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6339{
6340 return fNSFromRootmaps.count(nsDecl) != 0;
6341}
6342
6343////////////////////////////////////////////////////////////////////////////////
6344/// Internal function. Actually do the update of the ClassInfo when seeing
6345// new TagDecl or NamespaceDecl.
6346void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6347{
6348
6350 if (cci) {
6351 // If we only had a forward declaration then update the
6352 // TClingClassInfo with the definition if we have it now.
6353 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6354 if (!oldDef || (def && def != oldDef)) {
6355 cl->ResetCaches();
6357 if (def) {
6358 // It's a tag decl, not a namespace decl.
6359 cci->Init(*cci->GetType());
6361 }
6362 }
6363 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6364 cl->ResetCaches();
6365 // yes, this is almost a waste of time, but we do need to lookup
6366 // the 'type' corresponding to the TClass anyway in order to
6367 // preserve the opaque typedefs (Double32_t)
6368 if (!alias && def != nullptr)
6369 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(fInterpreter, def);
6370 else
6371 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(fInterpreter, cl->GetName());
6372 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6373 // We now need to update the state and bits.
6374 if (cl->fState != TClass::kHasTClassInit) {
6375 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6378 }
6379 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6380 } else {
6381 delete ((TClingClassInfo *)cl->fClassInfo);
6382 cl->fClassInfo = nullptr;
6383 }
6384 }
6385}
6386
6387////////////////////////////////////////////////////////////////////////////////
6388/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6389void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6390{
6391 const TagDecl *td = dyn_cast<TagDecl>(ND);
6392 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6393 const NamedDecl *canon = nullptr;
6394
6395 std::string name;
6396 TagDecl* tdDef = 0;
6397 if (td) {
6398 canon = tdDef = td->getDefinition();
6399 // Let's pass the decl to the TClass only if it has a definition.
6400 if (!tdDef) return;
6401
6402 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6403 // Ignore incomplete definition.
6404 // Ignore declaration within a function.
6405 return;
6406 }
6407
6408 auto declName = tdDef->getNameAsString();
6409 // Check if we have registered the unqualified name into the list
6410 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6411 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6412 // the unqualified name is sufficient (and the fully qualified name might be
6413 // 'wrong' if there is difference in spelling in the template paramters (for example)
6414 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6415 // 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() );
6416 return;
6417 }
6418
6419 clang::QualType type(tdDef->getTypeForDecl(), 0);
6421 } else if (ns) {
6422 canon = ns->getCanonicalDecl();
6423 name = ND->getQualifiedNameAsString();
6424 } else {
6425 name = ND->getQualifiedNameAsString();
6426 }
6427
6428 // Supposedly we are being called while something is being
6429 // loaded ... let's now tell the autoloader to do the work
6430 // yet another time.
6431 SuspendAutoloadingRAII autoLoadOff(this);
6432 // FIXME: There can be more than one TClass for a single decl.
6433 // for example vector<double> and vector<Double32_t>
6434 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6435 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6436 RefreshClassInfo(cl, canon, false);
6437 }
6438 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6439 // and update them too:
6440 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6441 // RefreshClassInfo(cl, tdDef, true);
6442}
6443
6444////////////////////////////////////////////////////////////////////////////////
6445/// No op: see TClingCallbacks
6446
6447void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6448{
6449}
6450
6451//______________________________________________________________________________
6452//FIXME: Factor out that function in TClass, because TClass does it already twice
6453void TCling::UpdateClassInfoWork(const char* item)
6454{
6455 // This is a no-op as part of the API.
6456 // TCling uses UpdateClassInfoWithDecl() instead.
6457}
6458
6459////////////////////////////////////////////////////////////////////////////////
6460/// Update all canvases at end the terminal input command.
6461
6463{
6464 TIter next(gROOT->GetListOfCanvases());
6465 TVirtualPad* canvas;
6466 while ((canvas = (TVirtualPad*)next())) {
6467 canvas->Update();
6468 }
6469}
6470
6471////////////////////////////////////////////////////////////////////////////////
6472
6473void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6474 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6475
6476 // If the transaction does not contain anything we can return earlier.
6477 if (!HandleNewTransaction(T)) return;
6478
6479 bool isTUTransaction = false;
6480 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6481 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6482 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6483 // The is the first transaction, we have to expose to meta
6484 // what's already in the AST.
6485 isTUTransaction = true;
6486 }
6487 }
6488
6489 std::set<const void*> TransactionDeclSet;
6490 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6491 const clang::Decl* WrapperFD = T.getWrapperFD();
6492 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6493 I != E; ++I) {
6494 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6495 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6496 continue;
6497
6498 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6499 DE = I->m_DGR.end(); DI != DE; ++DI) {
6500 if (*DI == WrapperFD)
6501 continue;
6502 TransactionDeclSet.insert(*DI);
6503 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6504 }
6505 }
6506 }
6507
6508 // The above might trigger more decls to be deserialized.
6509 // Thus the iteration over the deserialized decls must be last.
6510 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6511 E = T.deserialized_decls_end(); I != E; ++I) {
6512 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6513 DE = I->m_DGR.end(); DI != DE; ++DI)
6514 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6515 //FIXME: HandleNewDecl should take DeclGroupRef
6516 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6517 modifiedTClasses);
6518 }
6519 }
6520
6521
6522 // When fully building the reflection info in TClass, a deserialization
6523 // could be triggered, which may result in request for building the
6524 // reflection info for the same TClass. This in turn will clear the caches
6525 // for the TClass in-flight and cause null ptr derefs.
6526 // FIXME: This is a quick fix, solving most of the issues. The actual
6527 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6528 // itself until the update is done.
6529 //
6530 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6531 std::vector<TClass*>::iterator it;
6532 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6533 ((TCling*)gCling)->GetModTClasses().begin(),
6534 ((TCling*)gCling)->GetModTClasses().end(),
6535 modifiedTClassesDiff.begin());
6536 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6537
6538 // Lock the TClass for updates
6539 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6540 modifiedTClassesDiff.end());
6541 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6542 E = modifiedTClassesDiff.end(); I != E; ++I) {
6543 // Make sure the TClass has not been deleted.
6544 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6545 continue;
6546 }
6547 // Could trigger deserialization of decls.
6548 cling::Interpreter::PushTransactionRAII RAII(fInterpreter);
6549 // Unlock the TClass for updates
6550 ((TCling*)gCling)->GetModTClasses().erase(*I);
6551
6552 }
6553}
6554
6555////////////////////////////////////////////////////////////////////////////////
6556/// Helper function to go through the members of a class or namespace and unload them.
6557
6558void TCling::UnloadClassMembers(TClass* cl, const clang::DeclContext* DC) {
6559
6560 TDataMember* var = 0;
6561 TFunction* function = 0;
6562 TEnum* e = 0;
6563 TFunctionTemplate* functiontemplate = 0;
6566 TListOfEnums* enums = (TListOfEnums*)cl->GetListOfEnums();
6568 for (DeclContext::decl_iterator RI = DC->decls_begin(), RE = DC->decls_end(); RI != RE; ++RI) {
6569 if (isa<VarDecl>(*RI) || isa<FieldDecl>(*RI)) {
6570 const clang::ValueDecl* VD = dyn_cast<ValueDecl>(*RI);
6571 var = (TDataMember*)datamembers->FindObject(VD->getNameAsString().c_str());
6572 if (var) {
6573 // Unload the global by setting the DataMemberInfo_t to 0
6574 datamembers->Unload(var);
6575 var->Update(0);
6576 }
6577 } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(*RI)) {
6578 function = (TFunction*)functions->FindObject(FD->getNameAsString().c_str());
6579 if (function) {
6580 functions->Unload(function);
6581 function->Update(0);
6582 }
6583 } else if (const EnumDecl* ED = dyn_cast<EnumDecl>(*RI)) {
6584 e = (TEnum*)enums->FindObject(ED->getNameAsString().c_str());
6585 if (e) {
6586 TIter iEnumConst(e->GetConstants());
6587 while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
6588 // Since the enum is already created and valid that ensures us that
6589 // we have the enum constants created as well.
6590 enumConst = (TEnumConstant*)datamembers->FindObject(enumConst->GetName());
6591 if (enumConst && enumConst->IsValid()) {
6592 datamembers->Unload(enumConst);
6593 enumConst->Update(0);
6594 }
6595 }
6596 enums->Unload(e);
6597 e->Update(0);
6598 }
6599 } else if (const FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(*RI)) {
6600 functiontemplate = (TFunctionTemplate*)functiontemplates->FindObject(FTD->getNameAsString().c_str());
6601 if (functiontemplate) {
6602 functiontemplates->Unload(functiontemplate);
6603 functiontemplate->Update(0);
6604 }
6605 }
6606 }
6607}
6608
6609////////////////////////////////////////////////////////////////////////////////
6610
6611void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6612{
6614
6615 // Unload the objects from the lists and update the objects' state.
6616 TListOfFunctions* functions = (TListOfFunctions*)gROOT->GetListOfGlobalFunctions();
6617 TListOfFunctionTemplates* functiontemplates = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
6618 TListOfEnums* enums = (TListOfEnums*)gROOT->GetListOfEnums();
6619 TListOfDataMembers* globals = (TListOfDataMembers*)gROOT->GetListOfGlobals();
6620 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6621 for(cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6622 I != E; ++I) {
6623 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6624 continue;
6625
6626 if (I->m_Call == cling::Transaction::kCCINone) {
6627 UpdateListsOnUnloaded(**iNested);
6628 ++iNested;
6629 continue;
6630 }
6631
6632 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6633 DE = I->m_DGR.end(); DI != DE; ++DI) {
6634
6635 // Do not mark a decl as unloaded if we are going to keep it
6636 // (because it comes from the pch) ...
6637 if ( (*DI)->isFromASTFile() )
6638 continue;
6639
6640 // Deal with global variables and global enum constants.
6641 if (isa<VarDecl>(*DI) || isa<EnumConstantDecl>(*DI)) {
6642 TObject *obj = globals->Find((TListOfDataMembers::DeclId_t)*DI);
6643 if (globals->GetClass()) {
6644 TDataMember* var = dynamic_cast<TDataMember*>(obj);
6645 if (var && var->IsValid()) {
6646 // Unload the global by setting the DataMemberInfo_t to 0
6647 globals->Unload(var);
6648 var->Update(0);
6649 }
6650 } else {
6651 TGlobal *g = dynamic_cast<TGlobal*>(obj);
6652 if (g && g->IsValid()) {
6653 // Unload the global by setting the DataMemberInfo_t to 0
6654 globals->Unload(g);
6655 g->Update(0);
6656 }
6657 }
6658 // Deal with global functions.
6659 } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(*DI)) {
6661 if (function && function->IsValid()) {
6662 functions->Unload(function);
6663 function->Update(0);
6664 }
6665 // Deal with global function templates.
6666 } else if (const FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(*DI)) {
6667 TFunctionTemplate* functiontemplate = (TFunctionTemplate*)functiontemplates->FindObject(FTD->getNameAsString().c_str());
6668 if (functiontemplate) {
6669 functiontemplates->Unload(functiontemplate);
6670 functiontemplate->Update(0);
6671 }
6672 // Deal with global enums.
6673 } else if (const EnumDecl* ED = dyn_cast<EnumDecl>(*DI)) {
6674 if (TEnum* e = (TEnum*)enums->Find((TListOfEnums::DeclId_t)ED)) {
6675 globals = (TListOfDataMembers*)gROOT->GetListOfGlobals();
6676 TIter iEnumConst(e->GetConstants());
6677 while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
6678 // Since the enum is already created and valid that ensures us that
6679 // we have the enum constants created as well.
6680 enumConst = (TEnumConstant*)globals->FindObject(enumConst->GetName());
6681 if (enumConst) {
6682 globals->Unload(enumConst);
6683 enumConst->Update(0);
6684 }
6685 }
6686 enums->Unload(e);
6687 e->Update(0);
6688 }
6689 // Deal with classes. Unload the class and the data members will be not accessible anymore
6690 // Cannot declare the members in a different declaration like redeclarable namespaces.
6691 } else if (const clang::RecordDecl* RD = dyn_cast<RecordDecl>(*DI)) {
6692 std::vector<TClass*> vectTClass;
6693 // Only update the TClass if the definition is being unloaded.
6694 if (RD->isCompleteDefinition()) {
6695 if (TClass::GetClass(RD, vectTClass)) {
6696 for (std::vector<TClass*>::iterator CI = vectTClass.begin(), CE = vectTClass.end();
6697 CI != CE; ++CI) {
6698 UnloadClassMembers((*CI), RD);
6699 (*CI)->ResetClassInfo();
6700 }
6701 }
6702 }
6703 // Deal with namespaces. Unload the members of the current redeclaration only.
6704 } else if (const clang::NamespaceDecl* ND = dyn_cast<NamespaceDecl>(*DI)) {
6705 std::vector<TClass*> vectTClass;
6706 if (TClass::GetClass(ND->getCanonicalDecl(), vectTClass)) {
6707 for (std::vector<TClass*>::iterator CI = vectTClass.begin(), CE = vectTClass.end();
6708 CI != CE; ++CI) {
6709 UnloadClassMembers((*CI), ND);
6710 if (ND->isOriginalNamespace()) {
6711 (*CI)->ResetClassInfo();
6712 }
6713 }
6714 }
6715 }
6716 }
6717 }
6718}
6719
6720////////////////////////////////////////////////////////////////////////////////
6721// If an autoparse was done during a transaction and that it is rolled back,
6722// we need to make sure the next request for the same autoparse will be
6723// honored.
6724void TCling::TransactionRollback(const cling::Transaction &T) {
6725 auto const &triter = fTransactionHeadersMap.find(&T);
6726 if (triter != fTransactionHeadersMap.end()) {
6727 std::size_t normNameHash = triter->second;
6728
6729 fLookedUpClasses.erase(normNameHash);
6730
6731 auto const &iter = fClassesHeadersMap.find(normNameHash);
6732 if (iter != fClassesHeadersMap.end()) {
6733 auto const &hNamesPtrs = iter->second;
6734 for (auto &hName : hNamesPtrs) {
6735 if (gDebug > 0) {
6736 Info("TransactionRollback",
6737 "Restoring ability to autoaparse: %s", hName);
6738 }
6739 fParsedPayloadsAddresses.erase(hName);
6740 }
6741 }
6742 }
6743}
6744
6745////////////////////////////////////////////////////////////////////////////////
6746
6747void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6748// UpdateListOfLoadedSharedLibraries();
6749}
6750
6751////////////////////////////////////////////////////////////////////////////////
6752
6753void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6755 fSharedLibs = "";
6756}
6757
6758////////////////////////////////////////////////////////////////////////////////
6759/// Return the list of shared libraries loaded into the process.
6760
6762{
6764 return fSharedLibs;
6765}
6766
6767////////////////////////////////////////////////////////////////////////////////
6768/// Get the list of shared libraries containing the code for class cls.
6769/// The first library in the list is the one containing the class, the
6770/// others are the libraries the first one depends on. Returns 0
6771/// in case the library is not found.
6772
6773const char* TCling::GetClassSharedLibs(const char* cls)
6774{
6775 if (!cls || !*cls) {
6776 return 0;
6777 }
6778 // lookup class to find list of libraries
6779 if (fMapfile) {
6780 TEnvRec* libs_record = 0;
6781 libs_record = fMapfile->Lookup(cls);
6782 if (libs_record) {
6783 const char* libs = libs_record->GetValue();
6784 return (*libs) ? libs : 0;
6785 }
6786 else {
6787 // Try the old format...
6788 TString c = TString("Library.") + cls;
6789 // convert "::" to "@@", we used "@@" because TEnv
6790 // considers "::" a terminator
6791 c.ReplaceAll("::", "@@");
6792 // convert "-" to " ", since class names may have
6793 // blanks and TEnv considers a blank a terminator
6794 c.ReplaceAll(" ", "-");
6795 // Use TEnv::Lookup here as the rootmap file must start with Library.
6796 // and do not support using any stars (so we do not need to waste time
6797 // with the search made by TEnv::GetValue).
6798 TEnvRec* libs_record = 0;
6799 libs_record = fMapfile->Lookup(c);
6800 if (libs_record) {
6801 const char* libs = libs_record->GetValue();
6802 return (*libs) ? libs : 0;
6803 }
6804 }
6805 }
6806 return 0;
6807}
6808
6809////////////////////////////////////////////////////////////////////////////////
6810/// Get the list a libraries on which the specified lib depends. The
6811/// returned string contains as first element the lib itself.
6812/// Returns 0 in case the lib does not exist or does not have
6813/// any dependencies.
6814
6815const char* TCling::GetSharedLibDeps(const char* lib)
6816{
6817 if (!fMapfile || !lib || !lib[0]) {
6818 return 0;
6819 }
6820 TString libname(lib);
6821 Ssiz_t idx = libname.Last('.');
6822 if (idx != kNPOS) {
6823 libname.Remove(idx);
6824 }
6825 TEnvRec* rec;
6826 TIter next(fMapfile->GetTable());
6827 size_t len = libname.Length();
6828 while ((rec = (TEnvRec*) next())) {
6829 const char* libs = rec->GetValue();
6830 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
6831 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
6832 return libs;
6833 }
6834 }
6835 return 0;
6836}
6837
6838////////////////////////////////////////////////////////////////////////////////
6839/// If error messages are disabled, the interpreter should suppress its
6840/// failures and warning messages from stdout.
6841
6843{
6844#if defined(R__MUST_REVISIT)
6845#if R__MUST_REVISIT(6,2)
6846 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
6847#endif
6848#endif
6849 return kTRUE;
6850}
6851
6852////////////////////////////////////////////////////////////////////////////////
6853/// If error messages are disabled, the interpreter should suppress its
6854/// failures and warning messages from stdout. Return the previous state.
6855
6857{
6858#if defined(R__MUST_REVISIT)
6859#if R__MUST_REVISIT(6,2)
6860 Warning("SetErrorMessages", "Interface not available yet.");
6861#endif
6862#endif
6864}
6865
6866////////////////////////////////////////////////////////////////////////////////
6867/// Refresh the list of include paths known to the interpreter and return it
6868/// with -I prepended.
6869
6871{
6873
6874 fIncludePath = "";
6875
6876 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
6877 //false - no system header, true - with flags.
6878 fInterpreter->GetIncludePaths(includePaths, false, true);
6879 if (const size_t nPaths = includePaths.size()) {
6880 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
6881
6882 for (size_t i = 0; i < nPaths; i += 2) {
6883 if (i)
6884 fIncludePath.Append(' ');
6885 fIncludePath.Append(includePaths[i].c_str());
6886
6887 if (includePaths[i] != "-I")
6888 fIncludePath.Append(' ');
6889 fIncludePath.Append('"');
6890 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
6891 fIncludePath.Append('"');
6892 }
6893 }
6894
6895 return fIncludePath;
6896}
6897
6898////////////////////////////////////////////////////////////////////////////////
6899/// Return the directory containing CINT's stl cintdlls.
6900
6901const char* TCling::GetSTLIncludePath() const
6902{
6903 return "";
6904}
6905
6906//______________________________________________________________________________
6907// M I S C
6908//______________________________________________________________________________
6909
6910int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
6911{
6912 // Interface to cling function
6913 return 0;
6914}
6915
6916////////////////////////////////////////////////////////////////////////////////
6917/// Interface to cling function
6918
6919int TCling::DisplayIncludePath(FILE *fout) const
6920{
6921 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
6922
6923 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
6924 //false - no system header, true - with flags.
6925 fInterpreter->GetIncludePaths(includePaths, false, true);
6926 if (const size_t nPaths = includePaths.size()) {
6927 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
6928
6929 std::string allIncludes("include path:");
6930 for (size_t i = 0; i < nPaths; i += 2) {
6931 allIncludes += ' ';
6932 allIncludes += includePaths[i];
6933
6934 if (includePaths[i] != "-I")
6935 allIncludes += ' ';
6936 allIncludes += includePaths[i + 1];
6937 }
6938
6939 fprintf(fout, "%s\n", allIncludes.c_str());
6940 }
6941
6942 return 0;
6943}
6944
6945////////////////////////////////////////////////////////////////////////////////
6946/// Interface to cling function
6947
6948void* TCling::FindSym(const char* entry) const
6949{
6950 return fInterpreter->getAddressOfGlobal(entry);
6951}
6952
6953////////////////////////////////////////////////////////////////////////////////
6954/// Let the interpreter issue a generic error, and set its error state.
6955
6956void TCling::GenericError(const char* error) const
6957{
6958#if defined(R__MUST_REVISIT)
6959#if R__MUST_REVISIT(6,2)
6960 Warning("GenericError","Interface not available yet.");
6961#endif
6962#endif
6963}
6964
6965////////////////////////////////////////////////////////////////////////////////
6966/// This routines used to return the address of the internal wrapper
6967/// function (of the interpreter) that was used to call *all* the
6968/// interpreted functions that were bytecode compiled (no longer
6969/// interpreted line by line). In Cling, there is no such
6970/// wrapper function.
6971/// In practice this routines was use to decipher whether the
6972/// pointer returns by InterfaceMethod could be used to uniquely
6973/// represent the function. In Cling if the function is in a
6974/// useable state (its compiled version is available), this is
6975/// always the case.
6976/// See TClass::GetMethod.
6977
6979{
6980 return 0;
6981}
6982
6983////////////////////////////////////////////////////////////////////////////////
6984/// Interface to cling function
6985
6987{
6988#if defined(R__MUST_REVISIT)
6989#if R__MUST_REVISIT(6,2)
6990 Warning("GetSecurityError", "Interface not available yet.");
6991#endif
6992#endif
6993 return 0;
6994}
6995
6996////////////////////////////////////////////////////////////////////////////////
6997/// Load a source file or library called path into the interpreter.
6998
6999int TCling::LoadFile(const char* path) const
7000{
7001 cling::Interpreter::CompilationResult compRes;
7002 HandleInterpreterException(fMetaProcessor, TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7003 return compRes == cling::Interpreter::kFailure;
7004}
7005
7006////////////////////////////////////////////////////////////////////////////////
7007/// Load the declarations from text into the interpreter.
7008/// Note that this cannot be (top level) statements; text must contain
7009/// top level declarations.
7010/// Returns true on success, false on failure.
7011
7012Bool_t TCling::LoadText(const char* text) const
7013{
7014 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7015}
7016
7017////////////////////////////////////////////////////////////////////////////////
7018/// Interface to cling function
7019
7020const char* TCling::MapCppName(const char* name) const
7021{
7022 TTHREAD_TLS_DECL(std::string,buffer);
7023 ROOT::TMetaUtils::GetCppName(buffer,name);
7024 return buffer.c_str();
7025}
7026
7027////////////////////////////////////////////////////////////////////////////////
7028/// [Place holder for Mutex Lock]
7029/// Provide the interpreter with a way to
7030/// acquire a lock used to protect critical section
7031/// of its code (non-thread safe parts).
7032
7033void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7034{
7035 // nothing to do for now.
7036}
7037
7038////////////////////////////////////////////////////////////////////////////////
7039/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7040/// release a lock used to protect critical section
7041/// of its code (non-thread safe parts).
7042
7043void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7044{
7045 // nothing to do for now.
7046}
7047
7048////////////////////////////////////////////////////////////////////////////////
7049/// Enable/Disable the Autoloading of libraries.
7050/// Returns the old value, i.e whether it was enabled or not.
7051
7052int TCling::SetClassAutoloading(int autoload) const
7053{
7054 if (!autoload && !fClingCallbacks) return false;
7055 if (!fAllowLibLoad) return false;
7056
7057 assert(fClingCallbacks && "We must have callbacks!");
7058 bool oldVal = fClingCallbacks->IsAutoloadingEnabled();
7060 return oldVal;
7061}
7062
7063////////////////////////////////////////////////////////////////////////////////
7064/// Enable/Disable the Autoparsing of headers.
7065/// Returns the old value, i.e whether it was enabled or not.
7066
7068{
7069 bool oldVal = fHeaderParsingOnDemand;
7070 fHeaderParsingOnDemand = autoparse;
7071 return oldVal;
7072}
7073
7074////////////////////////////////////////////////////////////////////////////////
7075/// Suspend the Autoparsing of headers.
7076/// Returns the old value, i.e whether it was suspended or not.
7077
7082 return old;
7083}
7084
7085////////////////////////////////////////////////////////////////////////////////
7086/// Set a callback to receive error messages.
7087
7088void TCling::SetErrmsgcallback(void* p) const
7089{
7090#if defined(R__MUST_REVISIT)
7091#if R__MUST_REVISIT(6,2)
7092 Warning("SetErrmsgcallback", "Interface not available yet.");
7093#endif
7094#endif
7095}
7096
7097
7098////////////////////////////////////////////////////////////////////////////////
7099/// Create / close a scope for temporaries. No-op for cling; use
7100/// cling::Value instead.
7101
7102void TCling::SetTempLevel(int val) const
7103{
7104}
7105
7106////////////////////////////////////////////////////////////////////////////////
7107
7108int TCling::UnloadFile(const char* path) const
7109{
7110 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7111 std::string canonical = DLM->lookupLibrary(path);
7112 if (canonical.empty()) {
7113 canonical = path;
7114 }
7115 // Unload a shared library or a source file.
7116 cling::Interpreter::CompilationResult compRes;
7117 HandleInterpreterException(fMetaProcessor, Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7118 return compRes == cling::Interpreter::kFailure;
7119}
7120
7121std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7122 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7123}
7124
7125////////////////////////////////////////////////////////////////////////////////
7126/// The call to Cling's tab complition.
7127
7128void TCling::CodeComplete(const std::string& line, size_t& cursor,
7129 std::vector<std::string>& completions)
7130{
7131 fInterpreter->codeComplete(line, cursor, completions);
7132}
7133
7134////////////////////////////////////////////////////////////////////////////////
7135/// Get the interpreter value corresponding to the statement.
7136int TCling::Evaluate(const char* code, TInterpreterValue& value)
7137{
7138 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7139 auto compRes = fInterpreter->evaluate(code, *V);
7140 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7141}
7142
7143////////////////////////////////////////////////////////////////////////////////
7144
7146{
7147 using namespace cling;
7148 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7150}
7151
7152////////////////////////////////////////////////////////////////////////////////
7153/// Register value as a temporary, extending its lifetime to that of the
7154/// interpreter. This is needed for TCling's compatibility interfaces
7155/// returning long - the address of the temporary objects.
7156/// As such, "simple" types don't need to be stored; they are returned by
7157/// value; only pointers / references / objects need to be stored.
7158
7160{
7161 if (value.isValid() && value.needsManagedAllocation()) {
7163 fTemporaries->push_back(value);
7164 }
7165}
7166
7167////////////////////////////////////////////////////////////////////////////////
7168/// If the interpreter encounters Name, check whether that is an object ROOT
7169/// could retrieve. To not re-read objects from disk, cache the name/object
7170/// pair for a given LookupCtx.
7171
7172TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7173{
7174 // The call to FindSpecialObject might induces any kind of use
7175 // of the interpreter ... (library loading, function calling, etc.)
7176 // ... and we _know_ we are in the middle of parsing, so let's make
7177 // sure to save the state and then restore it.
7178
7179 if (gDirectory) {
7180 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7181 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7182 auto iSpecObj = iSpecObjMap->second.find(Name);
7183 if (iSpecObj != iSpecObjMap->second.end()) {
7184 LookupCtx = gDirectory;
7185 return iSpecObj->second;
7186 }
7187 }
7188 }
7189
7190 // Save state of the PP
7191 Sema &SemaR = fInterpreter->getSema();
7192 ASTContext& C = SemaR.getASTContext();
7193 Preprocessor &PP = SemaR.getPreprocessor();
7194 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7195 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7196 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7197 // After we have saved the token reset the current one to something which
7198 // is safe (semi colon usually means empty decl)
7199 Token& Tok = const_cast<Token&>(P.getCurToken());
7200 Tok.setKind(tok::semi);
7201
7202 // We can't PushDeclContext, because we go up and the routine that pops
7203 // the DeclContext assumes that we drill down always.
7204 // We have to be on the global context. At that point we are in a
7205 // wrapper function so the parent context must be the global.
7206 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7207 SemaR.TUScope);
7208
7209 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7210 if (specObj) {
7211 if (!LookupCtx) {
7212 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7213 } else {
7214 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7215 }
7216 }
7217 return specObj;
7218}
7219
7220////////////////////////////////////////////////////////////////////////////////
7221/// Inject function as a friend into klass.
7222/// With function being f in void f() {new N::PrivKlass(); } this enables
7223/// I/O of non-public classes.
7224
7225void TCling::AddFriendToClass(clang::FunctionDecl* function,
7226 clang::CXXRecordDecl* klass) const
7227{
7228 using namespace clang;
7229 ASTContext& Ctx = klass->getASTContext();
7230 FriendDecl::FriendUnion friendUnion(function);
7231 // one dummy object for the source location
7232 SourceLocation sl;
7233 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7234 klass->pushFriendDecl(friendDecl);
7235}
7236
7237//______________________________________________________________________________
7238//
7239// DeclId getter.
7240//
7241
7242////////////////////////////////////////////////////////////////////////////////
7243/// Return a unique identifier of the declaration represented by the
7244/// CallFunc
7245
7247{
7248 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7249 return 0;
7250}
7251
7252////////////////////////////////////////////////////////////////////////////////
7253/// Return a (almost) unique identifier of the declaration represented by the
7254/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7255/// when the underlying class is a template instance involving one of the
7256/// opaque typedef.
7257
7259{
7260 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7261 return 0;
7262}
7263
7264////////////////////////////////////////////////////////////////////////////////
7265/// Return a unique identifier of the declaration represented by the
7266/// MethodInfo
7267
7268TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7269{
7270 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7271 return 0;
7272}
7273
7274////////////////////////////////////////////////////////////////////////////////
7275/// Return a unique identifier of the declaration represented by the
7276/// MethodInfo
7277
7279{
7280 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7281 return 0;
7282}
7283
7284////////////////////////////////////////////////////////////////////////////////
7285/// Return a unique identifier of the declaration represented by the
7286/// TypedefInfo
7287
7289{
7290 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7291 return 0;
7292}
7293
7294//______________________________________________________________________________
7295//
7296// CallFunc interface
7297//
7298
7299////////////////////////////////////////////////////////////////////////////////
7300
7301void TCling::CallFunc_Delete(CallFunc_t* func) const
7302{
7303 delete (TClingCallFunc*) func;
7304}
7305
7306////////////////////////////////////////////////////////////////////////////////
7307
7308void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7309{
7310 TClingCallFunc* f = (TClingCallFunc*) func;
7311 f->Exec(address);
7312}
7313
7314////////////////////////////////////////////////////////////////////////////////
7315
7316void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7317{
7318 TClingCallFunc* f = (TClingCallFunc*) func;
7319 f->Exec(address, &val);
7320}
7321
7322////////////////////////////////////////////////////////////////////////////////
7323
7324void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7325{
7326 TClingCallFunc* f = (TClingCallFunc*) func;
7327 f->ExecWithReturn(address, ret);
7328}
7329
7330////////////////////////////////////////////////////////////////////////////////
7331
7332void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7333 const void* args[] /*=0*/,
7334 int nargs /*=0*/,
7335 void* ret/*=0*/) const
7336{
7337 TClingCallFunc* f = (TClingCallFunc*) func;
7338 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7339}
7340
7341////////////////////////////////////////////////////////////////////////////////
7342
7343Long_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7344{
7345 TClingCallFunc* f = (TClingCallFunc*) func;
7346 return f->ExecInt(address);
7347}
7348
7349////////////////////////////////////////////////////////////////////////////////
7350
7351Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7352{
7353 TClingCallFunc* f = (TClingCallFunc*) func;
7354 return f->ExecInt64(address);
7355}
7356
7357////////////////////////////////////////////////////////////////////////////////
7358
7359Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7360{
7361 TClingCallFunc* f = (TClingCallFunc*) func;
7362 return f->ExecDouble(address);
7363}
7364
7365////////////////////////////////////////////////////////////////////////////////
7366
7367CallFunc_t* TCling::CallFunc_Factory() const
7368{
7370 return (CallFunc_t*) new TClingCallFunc(fInterpreter,*fNormalizedCtxt);
7371}
7372
7373////////////////////////////////////////////////////////////////////////////////
7374
7375CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7376{
7377 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7378}
7379
7380////////////////////////////////////////////////////////////////////////////////
7381
7382MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7383{
7384 TClingCallFunc* f = (TClingCallFunc*) func;
7385 return (MethodInfo_t*) f->FactoryMethod();
7386}
7387
7388////////////////////////////////////////////////////////////////////////////////
7389
7390void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7391{
7392 TClingCallFunc* f = (TClingCallFunc*) func;
7393 f->IgnoreExtraArgs(ignore);
7394}
7395
7396////////////////////////////////////////////////////////////////////////////////
7397
7398void TCling::CallFunc_Init(CallFunc_t* func) const
7399{
7401 TClingCallFunc* f = (TClingCallFunc*) func;
7402 f->Init();
7403}
7404
7405////////////////////////////////////////////////////////////////////////////////
7406
7407bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7408{
7409 TClingCallFunc* f = (TClingCallFunc*) func;
7410 return f->IsValid();
7411}
7412
7413////////////////////////////////////////////////////////////////////////////////
7414
7416TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7417{
7418 TClingCallFunc* f = (TClingCallFunc*) func;
7419 return f->IFacePtr();
7420}
7421
7422////////////////////////////////////////////////////////////////////////////////
7423
7424void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7425{
7426 TClingCallFunc* f = (TClingCallFunc*) func;
7427 f->ResetArg();
7428}
7429
7430////////////////////////////////////////////////////////////////////////////////
7431
7432void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7433{
7434 TClingCallFunc* f = (TClingCallFunc*) func;
7435 f->SetArg(param);
7436}
7437
7438////////////////////////////////////////////////////////////////////////////////
7439
7440void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7441{
7442 TClingCallFunc* f = (TClingCallFunc*) func;
7443 f->SetArg(param);
7444}
7445
7446////////////////////////////////////////////////////////////////////////////////
7447
7448void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7449{
7450 TClingCallFunc* f = (TClingCallFunc*) func;
7451 f->SetArg(param);
7452}
7453
7454////////////////////////////////////////////////////////////////////////////////
7455
7456void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7457{
7458 TClingCallFunc* f = (TClingCallFunc*) func;
7459 f->SetArg(param);
7460}
7461
7462////////////////////////////////////////////////////////////////////////////////
7463
7464void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7465{
7466 TClingCallFunc* f = (TClingCallFunc*) func;
7467 f->SetArg(param);
7468}
7469
7470////////////////////////////////////////////////////////////////////////////////
7471
7472void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7473{
7474 TClingCallFunc* f = (TClingCallFunc*) func;
7475 f->SetArg(param);
7476}
7477
7478////////////////////////////////////////////////////////////////////////////////
7479
7480void TCling::CallFunc_SetArgArray(CallFunc_t* func, Long_t* paramArr, Int_t nparam) const
7481{
7482 TClingCallFunc* f = (TClingCallFunc*) func;
7483 f->SetArgArray(paramArr, nparam);
7484}
7485
7486////////////////////////////////////////////////////////////////////////////////
7487
7488void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7489{
7490 TClingCallFunc* f = (TClingCallFunc*) func;
7491 f->SetArgs(param);
7492}
7493
7494////////////////////////////////////////////////////////////////////////////////
7495
7496void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Long_t* offset) const
7497{
7498 TClingCallFunc* f = (TClingCallFunc*) func;
7499 TClingClassInfo* ci = (TClingClassInfo*) info;
7500 f->SetFunc(ci, method, params, offset);
7501}
7502
7503////////////////////////////////////////////////////////////////////////////////
7504
7505void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Long_t* offset) const
7506{
7507 TClingCallFunc* f = (TClingCallFunc*) func;
7508 TClingClassInfo* ci = (TClingClassInfo*) info;
7509 f->SetFunc(ci, method, params, objectIsConst, offset);
7510}
7511////////////////////////////////////////////////////////////////////////////////
7512
7513void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
7514{
7515 TClingCallFunc* f = (TClingCallFunc*) func;
7516 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
7517 f->SetFunc(minfo);
7518}
7519
7520////////////////////////////////////////////////////////////////////////////////
7521/// Interface to cling function
7522
7523void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7524{
7525 TClingCallFunc* f = (TClingCallFunc*) func;
7526 TClingClassInfo* ci = (TClingClassInfo*) info;
7527 f->SetFuncProto(ci, method, proto, offset, mode);
7528}
7529
7530////////////////////////////////////////////////////////////////////////////////
7531/// Interface to cling function
7532
7533void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7534{
7535 TClingCallFunc* f = (TClingCallFunc*) func;
7536 TClingClassInfo* ci = (TClingClassInfo*) info;
7537 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
7538}
7539
7540////////////////////////////////////////////////////////////////////////////////
7541/// Interface to cling function
7542
7543void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7544{
7545 TClingCallFunc* f = (TClingCallFunc*) func;
7546 TClingClassInfo* ci = (TClingClassInfo*) info;
7547 llvm::SmallVector<clang::QualType, 4> funcProto;
7548 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7549 iter != end; ++iter) {
7550 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7551 }
7552 f->SetFuncProto(ci, method, funcProto, offset, mode);
7553}
7554
7555////////////////////////////////////////////////////////////////////////////////
7556/// Interface to cling function
7557
7558void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7559{
7560 TClingCallFunc* f = (TClingCallFunc*) func;
7561 TClingClassInfo* ci = (TClingClassInfo*) info;
7562 llvm::SmallVector<clang::QualType, 4> funcProto;
7563 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7564 iter != end; ++iter) {
7565 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7566 }
7567 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
7568}
7569
7570std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
7571{
7572 TClingCallFunc *f = (TClingCallFunc *)func;
7573 std::string wrapper_name;
7574 std::string wrapper;
7575 f->get_wrapper_code(wrapper_name, wrapper);
7576 return wrapper;
7577}
7578
7579//______________________________________________________________________________
7580//
7581// ClassInfo interface
7582//
7583
7584////////////////////////////////////////////////////////////////////////////////
7585/// Return true if the entity pointed to by 'declid' is declared in
7586/// the context described by 'info'. If info is null, look into the
7587/// global scope (translation unit scope).
7588
7589Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
7590{
7591 if (!declid) return kFALSE;
7592
7593 const clang::Decl *scope;
7594 if (info) scope = ((TClingClassInfo*)info)->GetDecl();
7595 else scope = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
7596
7597 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
7598 const clang::DeclContext *ctxt = clang::Decl::castToDeclContext(scope);
7599 if (!decl || !ctxt) return kFALSE;
7600 if (decl->getDeclContext()->Equals(ctxt))
7601 return kTRUE;
7602 else if (decl->getDeclContext()->isTransparentContext() &&
7603 decl->getDeclContext()->getParent()->Equals(ctxt))
7604 return kTRUE;
7605 return kFALSE;
7606}
7607
7608////////////////////////////////////////////////////////////////////////////////
7609
7611{
7612 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7613 return TClinginfo->ClassProperty();
7614}
7615
7616////////////////////////////////////////////////////////////////////////////////
7617
7618void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
7619{
7620 delete (TClingClassInfo*) cinfo;
7621}
7622
7623////////////////////////////////////////////////////////////////////////////////
7624
7625void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
7626{
7627 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7628 TClinginfo->Delete(arena,*fNormalizedCtxt);
7629}
7630
7631////////////////////////////////////////////////////////////////////////////////
7632
7633void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
7634{
7635 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7636 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
7637}
7638
7639////////////////////////////////////////////////////////////////////////////////
7640
7641void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
7642{
7643 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7644 TClinginfo->Destruct(arena,*fNormalizedCtxt);
7645}
7646
7647////////////////////////////////////////////////////////////////////////////////
7648
7649ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
7650{
7652 return (ClassInfo_t*) new TClingClassInfo(fInterpreter, all);
7653}
7654
7655////////////////////////////////////////////////////////////////////////////////
7656
7657ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
7658{
7659 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
7660}
7661
7662////////////////////////////////////////////////////////////////////////////////
7663
7664ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
7665{
7667 return (ClassInfo_t*) new TClingClassInfo(fInterpreter, name);
7668}
7669
7670ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
7671{
7673 return (ClassInfo_t*) new TClingClassInfo(fInterpreter, (const clang::Decl*)declid);
7674}
7675
7676
7677////////////////////////////////////////////////////////////////////////////////
7678
7679int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
7680{
7681 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7682 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
7683}
7684
7685////////////////////////////////////////////////////////////////////////////////
7686
7687bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo) const
7688{
7689 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7690 return TClinginfo->HasDefaultConstructor();
7691}
7692
7693////////////////////////////////////////////////////////////////////////////////
7694
7695bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
7696{
7697 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7698 return TClinginfo->HasMethod(name);
7699}
7700
7701////////////////////////////////////////////////////////////////////////////////
7702
7703void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
7704{
7706 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7707 TClinginfo->Init(name);
7708}
7709
7710////////////////////////////////////////////////////////////////////////////////
7711
7712void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
7713{
7715 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7716 TClinginfo->Init(tagnum);
7717}
7718
7719////////////////////////////////////////////////////////////////////////////////
7720
7721bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
7722{
7723 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7724 return TClinginfo->IsBase(name);
7725}
7726
7727////////////////////////////////////////////////////////////////////////////////
7728
7729bool TCling::ClassInfo_IsEnum(const char* name) const
7730{
7732}
7733
7734////////////////////////////////////////////////////////////////////////////////
7735
7737{
7738 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
7739 return TClinginfo->IsScopedEnum();
7740}
7741
7742
7743////////////////////////////////////////////////////////////////////////////////
7744
7746{
7747 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
7748 return TClinginfo->GetUnderlyingType();
7749}
7750
7751
7752////////////////////////////////////////////////////////////////////////////////
7753
7754bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
7755{
7756 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7757 return TClinginfo->IsLoaded();
7758}
7759
7760////////////////////////////////////////////////////////////////////////////////
7761
7762bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
7763{
7764 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7765 return TClinginfo->IsValid();
7766}
7767
7768////////////////////////////////////////////////////////////////////////////////
7769
7770bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7771{
7772 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7773 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
7774}
7775
7776////////////////////////////////////////////////////////////////////////////////
7777
7778bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7779{
7780 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7781 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
7782}
7783
7784////////////////////////////////////////////////////////////////////////////////
7785
7786int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
7787{
7788 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7789 return TClinginfo->Next();
7790}
7791
7792////////////////////////////////////////////////////////////////////////////////
7793
7794void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
7795{
7796 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7797 return TClinginfo->New(*fNormalizedCtxt);
7798}
7799
7800////////////////////////////////////////////////////////////////////////////////
7801
7802void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
7803{
7804 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7805 return TClinginfo->New(n,*fNormalizedCtxt);
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809
7810void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
7811{
7812 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7813 return TClinginfo->New(n, arena,*fNormalizedCtxt);
7814}
7815
7816////////////////////////////////////////////////////////////////////////////////
7817
7818void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
7819{
7820 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7821 return TClinginfo->New(arena,*fNormalizedCtxt);
7822}
7823
7824////////////////////////////////////////////////////////////////////////////////
7825
7826Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
7827{
7828 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7829 return TClinginfo->Property();
7830}
7831
7832////////////////////////////////////////////////////////////////////////////////
7833
7834int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
7835{
7836 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7837 return TClinginfo->Size();
7838}
7839
7840////////////////////////////////////////////////////////////////////////////////
7841
7842Long_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
7843{
7844 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7845 return TClinginfo->Tagnum();
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849
7850const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
7851{
7852 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7853 return TClinginfo->FileName();
7854}
7855
7856////////////////////////////////////////////////////////////////////////////////
7857
7858const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
7859{
7860 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7861 TTHREAD_TLS_DECL(std::string,output);
7862 TClinginfo->FullName(output,*fNormalizedCtxt);
7863 return output.c_str();
7864}
7865
7866////////////////////////////////////////////////////////////////////////////////
7867
7868const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
7869{
7870 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7871 return TClinginfo->Name();
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
7877{
7878 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7879 return TClinginfo->Title();
7880}
7881
7882////////////////////////////////////////////////////////////////////////////////
7883
7884const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
7885{
7886 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7887 return TClinginfo->TmpltName();
7888}
7889
7890
7891
7892//______________________________________________________________________________
7893//
7894// BaseClassInfo interface
7895//
7896
7897////////////////////////////////////////////////////////////////////////////////
7898
7899void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
7900{
7901 delete(TClingBaseClassInfo*) bcinfo;
7902}
7903
7904////////////////////////////////////////////////////////////////////////////////
7905
7906BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
7907{
7909 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7910 return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo);
7911}
7912
7913////////////////////////////////////////////////////////////////////////////////
7914
7915BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
7916 ClassInfo_t* base) const
7917{
7919 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
7920 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
7921 return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo, TClinginfoBase);
7922}
7923
7924////////////////////////////////////////////////////////////////////////////////
7925
7926int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
7927{
7928 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7929 return TClinginfo->Next();
7930}
7931
7932////////////////////////////////////////////////////////////////////////////////
7933
7934int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
7935{
7936 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7937 return TClinginfo->Next(onlyDirect);
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941
7942Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
7943{
7944 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
7945 return TClinginfo->Offset(address, isDerivedObject);
7946}
7947
7948////////////////////////////////////////////////////////////////////////////////
7949
7950Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
7951{
7952 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
7953 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
7954 // Offset to the class itself.
7955 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
7956 return 0;
7957 }
7958 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
7959}
7960
7961////////////////////////////////////////////////////////////////////////////////
7962
7963Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
7964{
7965 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7966 return TClinginfo->Property();
7967}
7968
7969////////////////////////////////////////////////////////////////////////////////
7970
7971ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
7972{
7973 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7974 return (ClassInfo_t *)TClinginfo->GetBase();
7975}
7976
7977////////////////////////////////////////////////////////////////////////////////
7978
7979Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
7980{
7981 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7982 return TClinginfo->Tagnum();
7983}
7984
7985////////////////////////////////////////////////////////////////////////////////
7986
7987const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
7988{
7989 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
7990 TTHREAD_TLS_DECL(std::string,output);
7991 TClinginfo->FullName(output,*fNormalizedCtxt);
7992 return output.c_str();
7993}
7994
7995////////////////////////////////////////////////////////////////////////////////
7996
7997const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
7998{
7999 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8000 return TClinginfo->Name();
8001}
8002
8003////////////////////////////////////////////////////////////////////////////////
8004
8005const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8006{
8007 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8008 return TClinginfo->TmpltName();
8009}
8010
8011//______________________________________________________________________________
8012//
8013// DataMemberInfo interface
8014//
8015
8016////////////////////////////////////////////////////////////////////////////////
8017
8018int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8019{
8020 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8021 return TClinginfo->ArrayDim();
8022}
8023
8024////////////////////////////////////////////////////////////////////////////////
8025
8026void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8027{
8028 delete(TClingDataMemberInfo*) dminfo;
8029}
8030
8031////////////////////////////////////////////////////////////////////////////////
8032
8033DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo /*= 0*/) const
8034{
8036 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8037 return (DataMemberInfo_t*) new TClingDataMemberInfo(fInterpreter, TClingclass_info);
8038}
8039
8040////////////////////////////////////////////////////////////////////////////////
8041
8042DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8043{
8045 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8046 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8047 return (DataMemberInfo_t*) new TClingDataMemberInfo(fInterpreter, vd, (TClingClassInfo*)clinfo);
8048}
8049
8050////////////////////////////////////////////////////////////////////////////////
8051
8052DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8053{
8054 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8055 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8056}
8057
8058////////////////////////////////////////////////////////////////////////////////
8059
8060bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8061{
8062 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8063 return TClinginfo->IsValid();
8064}
8065
8066////////////////////////////////////////////////////////////////////////////////
8067
8068int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8069{
8070 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8071 return TClinginfo->MaxIndex(dim);
8072}
8073
8074////////////////////////////////////////////////////////////////////////////////
8075
8076int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8077{
8078 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8079 return TClinginfo->Next();
8080}
8081
8082////////////////////////////////////////////////////////////////////////////////
8083
8084Long_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8085{
8086 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8087 return TClinginfo->Offset();
8088}
8089
8090////////////////////////////////////////////////////////////////////////////////
8091
8092Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8093{
8094 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8095 return TClinginfo->Property();
8096}
8097
8098////////////////////////////////////////////////////////////////////////////////
8099
8100Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8101{
8102 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8103 return TClinginfo->TypeProperty();
8104}
8105
8106////////////////////////////////////////////////////////////////////////////////
8107
8108int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8109{
8110 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8111 return TClinginfo->TypeSize();
8112}
8113
8114////////////////////////////////////////////////////////////////////////////////
8115
8116const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8117{
8118 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8119 return TClinginfo->TypeName();
8120}
8121
8122////////////////////////////////////////////////////////////////////////////////
8123
8124const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8125{
8126 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8127 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8128}
8129
8130////////////////////////////////////////////////////////////////////////////////
8131
8132const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8133{
8134 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8135 return TClinginfo->Name();
8136}
8137
8138////////////////////////////////////////////////////////////////////////////////
8139
8140const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8141{
8142 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8143 return TClinginfo->Title();
8144}
8145
8146////////////////////////////////////////////////////////////////////////////////
8147
8148const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8149{
8150 TTHREAD_TLS_DECL(std::string,result);
8151
8152 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8153 result = TClinginfo->ValidArrayIndex().str();
8154 return result.c_str();
8155}
8156
8157////////////////////////////////////////////////////////////////////////////////
8158
8159void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8160{
8161 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8162 ASTContext &C = decl->getASTContext();
8163 SourceRange commentRange; // this is a fake comment range
8164 decl->addAttr( new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8165}
8166
8167//______________________________________________________________________________
8168//
8169// Function Template interface
8170//
8171
8172////////////////////////////////////////////////////////////////////////////////
8173
8174static void ConstructorName(std::string &name, const clang::NamedDecl *decl,
8175 cling::Interpreter &interp,
8176 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8177{
8178 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8179 if (!td) return;
8180
8181 clang::QualType qualType(td->getTypeForDecl(),0);
8182 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8183 unsigned int level = 0;
8184 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8185 if (name[cursor] == '>') ++level;
8186 else if (name[cursor] == '<' && level) --level;
8187 else if (level == 0 && name[cursor] == ':') {
8188 name.erase(0,cursor+1);
8189 break;
8190 }
8191 }
8192}
8193
8194////////////////////////////////////////////////////////////////////////////////
8195
8196void TCling::GetFunctionName(const clang::FunctionDecl *decl, std::string &output) const
8197{
8198 output.clear();
8199 if (llvm::isa<clang::CXXConstructorDecl>(decl))
8200 {
8202
8203 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8204 {
8206 output.insert(output.begin(), '~');
8207 } else {
8208 llvm::raw_string_ostream stream(output);
8209 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8210 // Don't trigger fopen of the source file to count lines:
8211 printPolicy.AnonymousTagLocations = false;
8212 decl->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8213 }
8214}
8215
8216////////////////////////////////////////////////////////////////////////////////
8217/// Return a unique identifier of the declaration represented by the
8218/// FuncTempInfo
8219
8221{
8222 return (DeclId_t)info;
8223}
8224
8225////////////////////////////////////////////////////////////////////////////////
8226/// Delete the FuncTempInfo_t
8227
8228void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8229{
8230 // Currently the address of ft_info is actually the decl itself,
8231 // so we have nothing to do.
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235/// Construct a FuncTempInfo_t
8236
8237FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8238{
8239 // Currently the address of ft_info is actually the decl itself,
8240 // so we have nothing to do.
8241
8242 return (FuncTempInfo_t*)const_cast<void*>(declid);
8243}
8244
8245////////////////////////////////////////////////////////////////////////////////
8246/// Construct a FuncTempInfo_t
8247
8248FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8249{
8250 // Currently the address of ft_info is actually the decl itself,
8251 // so we have nothing to do.
8252
8253 return (FuncTempInfo_t*)ft_info;
8254}
8255
8256////////////////////////////////////////////////////////////////////////////////
8257/// Check validity of a FuncTempInfo_t
8258
8259Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8260{
8261 // Currently the address of ft_info is actually the decl itself,
8262 // so we have nothing to do.
8263
8264 return t_info != 0;
8265}
8266
8267////////////////////////////////////////////////////////////////////////////////
8268/// Return the maximum number of template arguments of the
8269/// function template described by ft_info.
8270
8271UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8272{
8273 if (!ft_info) return 0;
8274 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8275 return ft->getTemplateParameters()->size();
8276}
8277
8278////////////////////////////////////////////////////////////////////////////////
8279/// Return the number of required template arguments of the
8280/// function template described by ft_info.
8281
8283{
8284 if (!ft_info) return 0;
8285 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8286 return ft->getTemplateParameters()->getMinRequiredArguments();
8287}
8288
8289////////////////////////////////////////////////////////////////////////////////
8290/// Return the property of the function template.
8291
8292Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8293{
8294 if (!ft_info) return 0;
8295
8296 long property = 0L;
8297 property |= kIsCompiled;
8298
8299 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8300
8301 switch (ft->getAccess()) {
8302 case clang::AS_public:
8303 property |= kIsPublic;
8304 break;
8305 case clang::AS_protected:
8306 property |= kIsProtected;
8307 break;
8308 case clang::AS_private:
8309 property |= kIsPrivate;
8310 break;
8311 case clang::AS_none:
8312 if (ft->getDeclContext()->isNamespace())
8313 property |= kIsPublic;
8314 break;
8315 default:
8316 // IMPOSSIBLE
8317 break;
8318 }
8319
8320 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8321 if (const clang::CXXMethodDecl *md =
8322 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8323 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
8324 property |= kIsConstant | kIsConstMethod;
8325 }
8326 if (md->isVirtual()) {
8327 property |= kIsVirtual;
8328 }
8329 if (md->isPure()) {
8330 property |= kIsPureVirtual;
8331 }
8332 if (const clang::CXXConstructorDecl *cd =
8333 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8334 if (cd->isExplicit()) {
8335 property |= kIsExplicit;
8336 }
8337 }
8338 else if (const clang::CXXConversionDecl *cd =
8339 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8340 if (cd->isExplicit()) {
8341 property |= kIsExplicit;
8342 }
8343 }
8344 }
8345 return property;
8346}
8347
8348////////////////////////////////////////////////////////////////////////////////
8349/// Return the property not already defined in Property
8350/// See TDictionary's EFunctionProperty
8351
8352Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8353{
8354 if (!ft_info) return 0;
8355
8356 long property = 0L;
8357 property |= kIsCompiled;
8358
8359 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8360 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8361
8362 if (fd->isOverloadedOperator()) {
8363 property |= kIsOperator;
8364 }
8365 else if (llvm::isa<clang::CXXConversionDecl>(fd)) {
8366 property |= kIsConversion;
8367 } else if (llvm::isa<clang::CXXConstructorDecl>(fd)) {
8368 property |= kIsConstructor;
8369 } else if (llvm::isa<clang::CXXDestructorDecl>(fd)) {
8370 property |= kIsDestructor;
8371 }
8372
8373 return property;
8374}
8375
8376////////////////////////////////////////////////////////////////////////////////
8377/// Return the name of this function template.
8378
8379void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8380{
8381 output.Clear();
8382 if (!ft_info) return;
8383 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8384 std::string buf;
8385 GetFunctionName(ft->getTemplatedDecl(), buf);
8386 output = buf;
8387}
8388
8389////////////////////////////////////////////////////////////////////////////////
8390/// Return the comments associates with this function template.
8391
8392void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8393{
8394 output.Clear();
8395 if (!ft_info) return;
8396 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8397
8398 // Iterate over the redeclarations, we can have multiple definitions in the
8399 // redecl chain (came from merging of pcms).
8400 if (const RedeclarableTemplateDecl *AnnotFD
8401 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8402 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8403 output = A->getAnnotation().str();
8404 return;
8405 }
8406 }
8407 if (!ft->isFromASTFile()) {
8408 // Try to get the comment from the header file if present
8409 // but not for decls from AST file, where rootcling would have
8410 // created an annotation
8411 output = ROOT::TMetaUtils::GetComment(*ft).str();
8412 }
8413}
8414
8415
8416//______________________________________________________________________________
8417//
8418// MethodInfo interface
8419//
8420
8421////////////////////////////////////////////////////////////////////////////////
8422/// Interface to cling function
8423
8424void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8425{
8426 delete(TClingMethodInfo*) minfo;
8427}
8428
8429////////////////////////////////////////////////////////////////////////////////
8430
8431void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8432{
8433 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8434 info->CreateSignature(signature);
8435}
8436
8437////////////////////////////////////////////////////////////////////////////////
8438
8439MethodInfo_t* TCling::MethodInfo_Factory() const
8440{
8442 return (MethodInfo_t*) new TClingMethodInfo(fInterpreter);
8443}
8444
8445////////////////////////////////////////////////////////////////////////////////
8446
8447MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8448{
8450 return (MethodInfo_t*) new TClingMethodInfo(fInterpreter, (TClingClassInfo*)clinfo);
8451}
8452
8453////////////////////////////////////////////////////////////////////////////////
8454
8455MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8456{
8457 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8459 const clang::FunctionDecl* fd = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl);
8460 return (MethodInfo_t*) new TClingMethodInfo(fInterpreter, fd);
8461}
8462
8463////////////////////////////////////////////////////////////////////////////////
8464
8465MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
8466{
8467 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8468}
8469
8470////////////////////////////////////////////////////////////////////////////////
8471
8472void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
8473{
8474 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8475 return info->InterfaceMethod(*fNormalizedCtxt);
8476}
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8480bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
8481{
8482 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8483 return info->IsValid();
8484}
8485
8486////////////////////////////////////////////////////////////////////////////////
8487
8488int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
8489{
8490 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8491 return info->NArg();
8492}
8493
8494////////////////////////////////////////////////////////////////////////////////
8495
8496int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
8497{
8498 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8499 return info->NDefaultArg();
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503
8504int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
8505{
8506 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8507 return info->Next();
8508}
8509
8510////////////////////////////////////////////////////////////////////////////////
8511
8512Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
8513{
8514 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8515 return info->Property();
8516}
8517
8518////////////////////////////////////////////////////////////////////////////////
8519
8521{
8522 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8523 return info->ExtraProperty();
8524}
8525
8526////////////////////////////////////////////////////////////////////////////////
8527
8528TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
8529{
8530 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8531 return (TypeInfo_t*)info->Type();
8532}
8533
8534////////////////////////////////////////////////////////////////////////////////
8535
8536const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
8537{
8538 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8539 TTHREAD_TLS_DECL(TString, mangled_name);
8540 mangled_name = info->GetMangledName();
8541 return mangled_name;
8542}
8543
8544////////////////////////////////////////////////////////////////////////////////
8545
8546const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
8547{
8548 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8549 return info->GetPrototype();
8550}
8551
8552////////////////////////////////////////////////////////////////////////////////
8553
8554const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
8555{
8556 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8557 return info->Name();
8558}
8559
8560////////////////////////////////////////////////////////////////////////////////
8561
8562const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
8563{
8564 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8565 return info->TypeName();
8566}
8567
8568////////////////////////////////////////////////////////////////////////////////
8569
8570std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
8571{
8572 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8573 if (info && info->IsValid())
8574 return info->Type()->NormalizedName(*fNormalizedCtxt);
8575 else
8576 return "";
8577}
8578
8579////////////////////////////////////////////////////////////////////////////////
8580
8581const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
8582{
8583 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8584 return info->Title();
8585}
8586
8587////////////////////////////////////////////////////////////////////////////////
8588
8590{
8591 if (func) {
8592 return MethodInfo_MethodCallReturnType(func->fInfo);
8593 } else {
8594 return EReturnType::kOther;
8595 }
8596}
8597
8598////////////////////////////////////////////////////////////////////////////////
8599
8601{
8602 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8603 if (info && info->IsValid()) {
8604 TClingTypeInfo *typeinfo = info->Type();
8605 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
8606 if (QT->isEnumeralType()) {
8607 return EReturnType::kLong;
8608 } else if (QT->isPointerType()) {
8609 // Look for char*
8610 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
8611 if ( QT->isCharType() ) {
8612 return EReturnType::kString;
8613 } else {
8614 return EReturnType::kOther;
8615 }
8616 } else if ( QT->isFloatingType() ) {
8617 int sz = typeinfo->Size();
8618 if (sz == 4 || sz == 8) {
8619 // Support only float and double.
8620 return EReturnType::kDouble;
8621 } else {
8622 return EReturnType::kOther;
8623 }
8624 } else if ( QT->isIntegerType() ) {
8625 int sz = typeinfo->Size();
8626 if (sz <= 8) {
8627 // Support only up to long long ... but
8628 // FIXME the TMethodCall::Execute only
8629 // return long (4 bytes) ...
8630 // The v5 implementation of TMethodCall::ReturnType
8631 // was not making the distinction so we let it go
8632 // as is for now, but we really need to upgrade
8633 // TMethodCall::Execute ...
8634 return EReturnType::kLong;
8635 } else {
8636 return EReturnType::kOther;
8637 }
8638 } else {
8639 return EReturnType::kOther;
8640 }
8641 } else {
8642 return EReturnType::kOther;
8643 }
8644}
8645
8646//______________________________________________________________________________
8647//
8648// MethodArgInfo interface
8649//
8650
8651////////////////////////////////////////////////////////////////////////////////
8652
8653void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
8654{
8655 delete(TClingMethodArgInfo*) marginfo;
8656}
8657
8658////////////////////////////////////////////////////////////////////////////////
8659
8660MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
8661{
8663 return (MethodArgInfo_t*) new TClingMethodArgInfo(fInterpreter);
8664}
8665
8666////////////////////////////////////////////////////////////////////////////////
8667
8668MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
8669{
8671 return (MethodArgInfo_t*) new TClingMethodArgInfo(fInterpreter, (TClingMethodInfo*)minfo);
8672}
8673
8674////////////////////////////////////////////////////////////////////////////////
8675
8676MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
8677{
8678 return (MethodArgInfo_t*)
8680}
8681
8682////////////////////////////////////////////////////////////////////////////////
8683
8684bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
8685{
8686 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8687 return info->IsValid();
8688}
8689
8690////////////////////////////////////////////////////////////////////////////////
8691
8692int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
8693{
8694 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8695 return info->Next();
8696}
8697
8698////////////////////////////////////////////////////////////////////////////////
8699
8700Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
8701{
8702 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8703 return info->Property();
8704}
8705
8706////////////////////////////////////////////////////////////////////////////////
8707
8708const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
8709{
8710 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8711 return info->DefaultValue();
8712}
8713
8714////////////////////////////////////////////////////////////////////////////////
8715
8716const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
8717{
8718 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8719 return info->Name();
8720}
8721
8722////////////////////////////////////////////////////////////////////////////////
8723
8724const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
8725{
8726 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8727 return info->TypeName();
8728}
8729
8730////////////////////////////////////////////////////////////////////////////////
8731
8732std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
8733{
8734 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8735 return info->Type()->NormalizedName(*fNormalizedCtxt);
8736}
8737
8738//______________________________________________________________________________
8739//
8740// TypeInfo interface
8741//
8742
8743////////////////////////////////////////////////////////////////////////////////
8744
8745void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
8746{
8747 delete (TClingTypeInfo*) tinfo;
8748}
8749
8750////////////////////////////////////////////////////////////////////////////////
8751
8752TypeInfo_t* TCling::TypeInfo_Factory() const
8753{
8755 return (TypeInfo_t*) new TClingTypeInfo(fInterpreter);
8756}
8757
8758////////////////////////////////////////////////////////////////////////////////
8759
8760TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
8761{
8763 return (TypeInfo_t*) new TClingTypeInfo(fInterpreter, name);
8764}
8765
8766////////////////////////////////////////////////////////////////////////////////
8767
8768TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
8769{
8770 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
8771}
8772
8773////////////////////////////////////////////////////////////////////////////////
8774
8775void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
8776{
8778 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8779 TClinginfo->Init(name);
8780}
8781
8782////////////////////////////////////////////////////////////////////////////////
8783
8784bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
8785{
8786 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8787 return TClinginfo->IsValid();
8788}
8789
8790////////////////////////////////////////////////////////////////////////////////
8791
8792const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
8793{
8794 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8795 return TClinginfo->Name();
8796}
8797
8798////////////////////////////////////////////////////////////////////////////////
8799
8800Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
8801{
8802 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8803 return TClinginfo->Property();
8804}
8805
8806////////////////////////////////////////////////////////////////////////////////
8807
8808int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
8809{
8810 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8811 return TClinginfo->RefType();
8812}
8813
8814////////////////////////////////////////////////////////////////////////////////
8815
8816int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
8817{
8818 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8819 return TClinginfo->Size();
8820}
8821
8822////////////////////////////////////////////////////////////////////////////////
8823
8824const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
8825{
8826 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
8827 return TClinginfo->TrueName(*fNormalizedCtxt);
8828}
8829
8830
8831//______________________________________________________________________________
8832//
8833// TypedefInfo interface
8834//
8835
8836////////////////////////////////////////////////////////////////////////////////
8837
8838void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
8839{
8840 delete(TClingTypedefInfo*) tinfo;
8841}
8842
8843////////////////////////////////////////////////////////////////////////////////
8844
8845TypedefInfo_t* TCling::TypedefInfo_Factory() const
8846{
8848 return (TypedefInfo_t*) new TClingTypedefInfo(fInterpreter);
8849}
8850
8851////////////////////////////////////////////////////////////////////////////////
8852
8853TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
8854{
8856 return (TypedefInfo_t*) new TClingTypedefInfo(fInterpreter, name);
8857}
8858
8859////////////////////////////////////////////////////////////////////////////////
8860
8861TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
8862{
8863 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
8864}
8865
8866////////////////////////////////////////////////////////////////////////////////
8867
8868void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
8869 const char* name) const
8870{
8872 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8873 TClinginfo->Init(name);
8874}
8875
8876////////////////////////////////////////////////////////////////////////////////
8877
8878bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
8879{
8880 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8881 return TClinginfo->IsValid();
8882}
8883
8884////////////////////////////////////////////////////////////////////////////////
8885
8886Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
8887{
8888 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8889 return TClinginfo->Next();
8890}
8891
8892////////////////////////////////////////////////////////////////////////////////
8893
8894Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
8895{
8896 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8897 return TClinginfo->Property();
8898}
8899
8900////////////////////////////////////////////////////////////////////////////////
8901
8902int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
8903{
8904 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8905 return TClinginfo->Size();
8906}
8907
8908////////////////////////////////////////////////////////////////////////////////
8909
8910const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
8911{
8912 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8913 return TClinginfo->TrueName(*fNormalizedCtxt);
8914}
8915
8916////////////////////////////////////////////////////////////////////////////////
8917
8918const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
8919{
8920 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8921 return TClinginfo->Name();
8922}
8923
8924////////////////////////////////////////////////////////////////////////////////
8925
8926const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
8927{
8928 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
8929 return TClinginfo->Title();
8930}
8931
8932////////////////////////////////////////////////////////////////////////////////
8933
8935{
8936 if (!fInitialMutex.back()) {
8937 if (fInitialMutex.back().fRecurseCount) {
8938 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
8939 }
8940 fInitialMutex.back().fState = mtx->GetStateBefore();
8941 }
8942 // We will "forget" this lock once we backed out of all interpreter frames.
8943 // Here we are entering one, so ++.
8944 ++fInitialMutex.back().fRecurseCount;
8945}
8946
8947////////////////////////////////////////////////////////////////////////////////
8948
8950{
8951 if (!fInitialMutex.back())
8952 return;
8953 if (fInitialMutex.back().fRecurseCount == 0) {
8954 Error("ForgetMutexState", "mutex state's recurse count already 0!");
8955 }
8956 else if (--fInitialMutex.back().fRecurseCount == 0) {
8957 // We have returned from all interpreter frames. Reset the initial lock state.
8958 fInitialMutex.back().fState.reset();
8959 }
8960}
8961
8962////////////////////////////////////////////////////////////////////////////////
8963/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
8964
8966{
8967 R__ASSERT(!fInitialMutex.empty() && "Inconsistent state of fInitialMutex!");
8968 if (gInterpreterMutex) {
8969 if (delta) {
8970 auto typedDelta = static_cast<TVirtualRWMutex::StateDelta *>(delta);
8971 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP{typedDelta};
8972 gCoreMutex->Apply(std::move(uniqueP));
8973 }
8974 }
8975 fInitialMutex.pop_back();
8976}
8977
8978////////////////////////////////////////////////////////////////////////////////
8979/// Reset the interpreter lock to the state it had before interpreter-related
8980/// calls happened.
8981
8983{
8984 if (fInitialMutex.back()) {
8985 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP = gCoreMutex->Rewind(*fInitialMutex.back().fState);
8986 // Need to start a new recurse count.
8987 fInitialMutex.emplace_back();
8988 return uniqueP.release();
8989 }
8990 // Need to start a new recurse count.
8991 fInitialMutex.emplace_back();
8992 return nullptr;
8993}
void Class()
Definition: Class.C:29
#define R__EXTERN
Definition: DllImport.h:27
#define d(i)
Definition: RSha256.hxx:102
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
#define e(i)
Definition: RSha256.hxx:103
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
int Ssiz_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
unsigned long long ULong64_t
Definition: RtypesCore.h:70
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:78
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:95
static void indent(ostringstream &buf, int indent_level)
std::string AlternateTuple(const char *classname)
Definition: TCling.cxx:3545
static bool requiresRootMap(const char *rootmapfile, cling::Interpreter *interp)
Definition: TCling.cxx:5043
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:330
void TCling__FindLoadedLibraries(std::vector< std::pair< uint32_t, std::string > > &sLibraries, std::vector< std::string > &sPaths, cling::Interpreter &interpreter, bool searchSystem)
void * llvmLazyFunctionCreator(const std::string &mangled_name)
Autoload a library provided the mangled name of a missing symbol.
Definition: TCling.cxx:691
void TCling__TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:565
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition: TCling.cxx:903
R__EXTERN int optind
Definition: TCling.cxx:314
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition: TCling.cxx:357
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition: TCling.cxx:559
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition: TCling.cxx:546
R__DLLEXPORT clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition: TCling.cxx:212
static std::string GetModuleNameAsString(clang::Module *M, const clang::Preprocessor &PP)
Definition: TCling.cxx:1100
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition: TCling.cxx:3503
static bool LookupNormalSymbols(llvm::object::ObjectFile *RealSoFile, const std::string &mangled_name, const std::string &LibName)
Definition: TCling.cxx:6083
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:340
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition: TCling.cxx:1701
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition: TCling.cxx:2823
R__DLLEXPORT void TCling__DEBUG__printName(clang::Decl *D)
Definition: TCling.cxx:233
R__DLLEXPORT void TCling__DEBUG__decl_dump(void *D)
Definition: TCling.cxx:230
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:912
R__DLLEXPORT clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition: TCling.cxx:215
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition: TCling.cxx:368
const char * TCling__GetClassSharedLibs(const char *className)
Definition: TCling.cxx:616
static uint32_t GNUHash(StringRef S)
Definition: TCling.cxx:6034
R__DLLEXPORT clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition: TCling.cxx:218
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition: TCling.cxx:1494
int TCling__AutoParseCallback(const char *className)
Definition: TCling.cxx:611
static void ConstructorName(std::string &name, const clang::NamedDecl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition: TCling.cxx:8174
int TCling_GenerateDictionary(const std::vector< std::string > &classes, const std::vector< std::string > &headers, const std::vector< std::string > &fwdDecls, const std::vector< std::string > &unknown)
Definition: TCling.cxx:701
static bool RegisterPrebuiltModulePath(clang::Preprocessor &PP, const std::string &FullPath)
Definition: TCling.cxx:1042
R__DLLEXPORT bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition: TCling.cxx:248
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp, bool Complain=true)
Definition: TCling.cxx:1069
R__DLLEXPORT void DestroyInterpreter(TInterpreter *interp)
Definition: TCling.cxx:599
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:576
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition: TCling.cxx:553
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition: TCling.cxx:588
static ETupleOrdering IsTupleAscending()
Definition: TCling.cxx:3521
R__DLLEXPORT TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition: TCling.cxx:592
R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition: TCling.cxx:221
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition: TCling.cxx:378
int TCling__CompileMacro(const char *fileName, const char *options)
Definition: TCling.cxx:633
#define R__DLLEXPORT
Definition: TCling.cxx:139
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:349
static std::string FindLibraryName(void(*func)())
Wrapper around dladdr (and friends)
Definition: TCling.cxx:1431
int TCling__AutoLoadCallback(const char *className)
Definition: TCling.cxx:606
static bool IsFromRootCling()
Definition: TCling.cxx:1094
void TCling__PrintStackTrace()
Print a StackTrace!
Definition: TCling.cxx:323
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:2156
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:674
const char * fantomline
Definition: TCling.cxx:850
static bool LookupBloomFilter(llvm::object::ObjectFile *soFile, uint32_t hash)
Definition: TCling.cxx:6060
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:570
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition: TCling.cxx:5765
static void * LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name, cling::Interpreter *fInterpreter)
Definition: TCling.cxx:6119
static StringRef GetGnuHashSection(llvm::object::ObjectFile *file)
Definition: TCling.cxx:6041
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition: TCling.cxx:584
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:1088
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition: TCling.cxx:628
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition: TCling.cxx:640
EDataType
Definition: TDataType.h:28
@ kULong64_t
Definition: TDataType.h:32
@ kLong64_t
Definition: TDataType.h:32
@ kIsDestructor
Definition: TDictionary.h:123
@ kIsConversion
Definition: TDictionary.h:122
@ kIsConstructor
Definition: TDictionary.h:121
@ kIsOperator
Definition: TDictionary.h:124
@ kIsPublic
Definition: TDictionary.h:74
@ kIsConstant
Definition: TDictionary.h:86
@ kIsConstMethod
Definition: TDictionary.h:92
@ kIsClass
Definition: TDictionary.h:65
@ kIsEnum
Definition: TDictionary.h:68
@ kIsPrivate
Definition: TDictionary.h:76
@ kIsCompiled
Definition: TDictionary.h:85
@ kIsStatic
Definition: TDictionary.h:79
@ kIsExplicit
Definition: TDictionary.h:90
@ kIsStruct
Definition: TDictionary.h:66
@ kIsProtected
Definition: TDictionary.h:75
@ kIsVirtual
Definition: TDictionary.h:72
@ kIsUnion
Definition: TDictionary.h:67
@ kIsPureVirtual
Definition: TDictionary.h:73
@ kIsNamespace
Definition: TDictionary.h:91
#define gDirectory
Definition: TDirectory.h:218
@ kEnvUser
Definition: TEnv.h:72
@ kEnvGlobal
Definition: TEnv.h:71
@ kEnvLocal
Definition: TEnv.h:73
#define R__ASSERT(e)
Definition: TError.h:96
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
const Int_t kWarning
Definition: TError.h:38
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
void Warning(const char *location, const char *msgfmt,...)
void Fatal(const char *location, const char *msgfmt,...)
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
#define R__LOCKGUARD_CLING(mutex)
Definition: TInterpreter.h:47
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:554
#define gInterpreter
Definition: TInterpreter.h:553
#define gROOT
Definition: TROOT.h:414
char * Form(const char *fmt,...)
typedef void((*Func_t)())
@ kReadPermission
Definition: TSystem.h:48
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:119
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
R__EXTERN TVirtualMutex * gGlobalMutex
Definition: TVirtualMutex.h:29
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition: civetweb.c:16604
#define free
Definition: civetweb.c:1539
#define snprintf
Definition: civetweb.c:1540
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static Long_t ExecuteFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
Definition: TApplication.h:131
virtual Bool_t IsCmdThread()
Definition: TApplication.h:130
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition: TClassRef.h:29
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static 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:75
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3288
EState GetState() const
Definition: TClass.h:458
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2813
EState fState
cached of the streaming method to use
Definition: TClass.h:242
std::atomic< TList * > fBase
Definition: TClass.h:176
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition: TClass.cxx:467
Version_t fClassVersion
Definition: TClass.h:195
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return list containing the TEnums of a class.
Definition: TClass.cxx:3670
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:4778
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition: TClass.cxx:492
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition: TClass.cxx:2124
std::atomic< TListOfEnums * > fEnums
Definition: TClass.h:179
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition: TClass.cxx:3247
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition: TClass.cxx:3579
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition: TClass.cxx:3684
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition: TClass.cxx:5736
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5528
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3635
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5483
@ kLoading
Definition: TClass.h:298
TObjArray * fStreamerInfo
Definition: TClass.h:173
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5691
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:404
ClassInfo_t * fClassInfo
Definition: TClass.h:196
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5817
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2824
void ResetCaches()
To clean out all caches.
Definition: TClass.cxx:4087
@ kInterpreted
Definition: TClass.h:120
@ kHasTClassInit
Definition: TClass.h:121
@ kEmulated
Definition: TClass.h:119
@ kForwardDeclared
Definition: TClass.h:118
@ kNamespaceForMeta
Definition: TClass.h:125
Version_t GetClassVersion() const
Definition: TClass.h:391
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition: TClass.h:224
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition: TClass.cxx:3312
@ kIsTObject
Definition: TClass.h:93
@ kIsEmulation
Definition: TClass.h:95
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:2895
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
long ExecInt(void *address)
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
void * InterfaceMethod()
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
void SetAutoloadingEnabled(bool val=true)
bool IsAutoloadingEnabled()
void SetAutoParsingSuspended(bool val=true)
Emulation of the CINT ClassInfo class.
bool HasDefaultConstructor() const
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
long Property() const
EDataType GetUnderlyingType() const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, long *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
bool IsScopedEnum() const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, long *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * Name() override
int MaxIndex(int dim) const
llvm::StringRef ValidArrayIndex() const
virtual const char * Name()
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
const char * Name() override
std::string GetMangledName() const
const char * TypeName() const
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * GetPrototype()
const clang::FunctionDecl * GetMethodDecl() const
long ExtraProperty() const
void CreateSignature(TString &signature) const
const char * Title()
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
bool IsValid() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
int Size() const
int RefType() const
const char * Name() const
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * Name() override
Get the name of the current typedef.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition: TClingValue.h:34
const char * Data()
Definition: TCling.cxx:1017
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition: TCling.cxx:1025
std::string fContent
Definition: TCling.h:571
This class defines an interface to the cling C++ interpreter.
Definition: TCling.h:89
virtual const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8708
virtual std::string CallFunc_GetWrapperCode(CallFunc_t *func) const
Definition: TCling.cxx:7570
virtual void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const
Return the name of this function template.
Definition: TCling.cxx:8379
virtual void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const
Return the comments associates with this function template.
Definition: TCling.cxx:8392
virtual int TypedefInfo_Next(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8886
virtual bool DiagnoseIfInterpreterException(const std::exception &e) const
Definition: TCling.cxx:2175
virtual bool ClassInfo_IsValid(ClassInfo_t *info) const
Definition: TCling.cxx:7762
virtual bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const
Definition: TCling.cxx:7736
Long_t Calc(const char *line, EErrorCode *error=0)
Directly execute an executable statement (e.g.
Definition: TCling.cxx:3193
Bool_t HasPCMForLibrary(const char *libname) const
Return true if ROOT has cxxmodules pcm for a given library name.
Definition: TCling.cxx:2841
virtual MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const
Definition: TCling.cxx:8465
bool LoadPCM(const std::string &pcmFileNameFullPath)
Tries to load a PCM; returns true on success.
Definition: TCling.cxx:1509
virtual const char * TypeInfo_Name(TypeInfo_t *) const
Definition: TCling.cxx:8792
DeclId_t GetFunction(ClassInfo_t *cl, const char *funcname)
Return pointer to cling interface function for a method of a class with a certain name.
Definition: TCling.cxx:4559
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition: TCling.cxx:6013
void ForgetMutexState()
Definition: TCling.cxx:8949
virtual bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:7695
std::vector< void * > fRegisterModuleDyLibs
Definition: TCling.h:126
virtual MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const
Definition: TCling.cxx:7382
virtual bool MethodInfo_IsValid(MethodInfo_t *minfo) const
Definition: TCling.cxx:8480
Bool_t fLockProcessLine
Definition: TCling.h:114
virtual const char * DataMemberInfo_TypeTrueName(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8124
void CreateListOfDataMembers(TClass *cl) const
Create list of pointers to data members for TClass cl.
Definition: TCling.cxx:4025
void UnRegisterTClassUpdate(const TClass *oldcl)
If the dictionary is loaded, we can remove the class from the list (otherwise the class might be load...
Definition: TCling.cxx:2126
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition: TCling.cxx:485
virtual const char * MethodInfo_TypeName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8562
virtual Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8894
virtual void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8653
Bool_t IsAutoLoadNamespaceCandidate(const char *name)
Definition: TCling.cxx:6328
virtual void LoadFunctionTemplates(TClass *cl) const
Create list of pointers to function templates for TClass cl.
Definition: TCling.cxx:3978
virtual CallFunc_t * CallFunc_Factory() const
Definition: TCling.cxx:7367
virtual TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8861
std::vector< const char * > fCurExecutingMacros
Definition: TCling.h:137
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition: TCling.cxx:6473
virtual void SetAllocunlockfunc(void(*)()) const
[Place holder for Mutex Unlock] Provide the interpreter with a way to release a lock used to protect ...
Definition: TCling.cxx:7043
virtual Long_t ClassInfo_Tagnum(ClassInfo_t *info) const
Definition: TCling.cxx:7842
void UpdateListOfTypes()
No op: see TClingCallbacks (used to update the list of types)
Definition: TCling.cxx:3497
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const
Return pointer to cling DeclId for a data member with a given name.
Definition: TCling.cxx:4480
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8018
virtual bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:7721
virtual int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7926
virtual void GenericError(const char *error) const
Let the interpreter issue a generic error, and set its error state.
Definition: TCling.cxx:6956
virtual std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8732
virtual const char * ClassInfo_TmpltName(ClassInfo_t *info) const
Definition: TCling.cxx:7884
virtual TEnum * CreateEnum(void *VD, TClass *cl) const
Definition: TCling.cxx:458
virtual EReturnType MethodCallReturnType(TFunction *func) const
Definition: TCling.cxx:8589
virtual int UnloadFile(const char *path) const
Definition: TCling.cxx:7108
virtual int Evaluate(const char *, TInterpreterValue &)
Get the interpreter value corresponding to the statement.
Definition: TCling.cxx:7136
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition: TCling.cxx:7172
virtual Long_t TypeInfo_Property(TypeInfo_t *tinfo) const
Definition: TCling.cxx:8800
DeclId_t GetFunctionWithPrototype(ClassInfo_t *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition: TCling.cxx:4678
void EndOfLineAction()
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition: TCling.cxx:2815
DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return pointer to cling DeclId for a method of a class with a certain prototype, i....
Definition: TCling.cxx:4656
void UpdateListOfLoadedSharedLibraries()
Definition: TCling.cxx:2961
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)
Inject the module named "modulename" into cling; load all headers.
Definition: TCling.cxx:1735
virtual const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8148
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e $ROOTSYS/etc/system<name> (...
Definition: TCling.cxx:5179
void CreateListOfMethodArgs(TFunction *m) const
Create list of pointers to method arguments for TMethod m.
Definition: TCling.cxx:4059
virtual void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const
Definition: TCling.cxx:8868
virtual Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const
Definition: TCling.cxx:8520
virtual ~TCling()
Destroy the interpreter interface.
Definition: TCling.cxx:1391
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition: TCling.cxx:7225
std::vector< MutexStateAndRecurseCount > fInitialMutex
Definition: TCling.h:155
Bool_t fCxxModulesEnabled
Definition: TCling.h:116
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition: TCling.cxx:6346
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:4908
virtual void FuncTempInfo_Delete(FuncTempInfo_t *) const
Delete the FuncTempInfo_t.
Definition: TCling.cxx:8228
Bool_t SetSuspendAutoParsing(Bool_t value)
Suspend the Autoparsing of headers.
Definition: TCling.cxx:7078
virtual DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8052
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const
Definition: TCling.cxx:7416
virtual void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const
Definition: TCling.cxx:7324
virtual MethodArgInfo_t * MethodArgInfo_Factory() const
Definition: TCling.cxx:8660
virtual void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8026
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:8965
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition: TCling.cxx:6234
virtual int LoadFile(const char *path) const
Load a source file or library called path into the interpreter.
Definition: TCling.cxx:6999
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &)
The call to Cling's tab complition.
Definition: TCling.cxx:7128
virtual int SetClassAutoloading(int) const
Enable/Disable the Autoloading of libraries.
Definition: TCling.cxx:7052
virtual Long_t FuncTempInfo_Property(FuncTempInfo_t *) const
Return the property of the function template.
Definition: TCling.cxx:8292
virtual TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const
Definition: TCling.cxx:8528
virtual const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8724
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition: TCling.cxx:3263
virtual bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8060
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:5063
Bool_t IsLoaded(const char *filename) const
Return true if the file has already been loaded by cint.
Definition: TCling.cxx:2860
const char * GetSharedLibs()
Return the list of shared libraries loaded into the process.
Definition: TCling.cxx:6761
virtual const char * GetTopLevelMacroName() const
Return the file name of the current un-included interpreted file.
Definition: TCling.cxx:4939
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition: TCling.h:141
virtual DeclId_t GetDataMemberWithValue(const void *ptrvalue) const
NOT IMPLEMENTED.
Definition: TCling.cxx:4471
virtual bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8684
Int_t ReloadAllSharedLibraryMaps()
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition: TCling.cxx:5459
virtual void SetErrmsgcallback(void *p) const
Set a callback to receive error messages.
Definition: TCling.cxx:7088
virtual std::string ToString(const char *type, void *obj)
Definition: TCling.cxx:1034
virtual const char * MethodInfo_Title(MethodInfo_t *minfo) const
Definition: TCling.cxx:8581
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const
Definition: TCling.cxx:7950
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8108
virtual ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const
Definition: TCling.cxx:7649
virtual const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8536
virtual bool CallFunc_IsValid(CallFunc_t *func) const
Definition: TCling.cxx:7407
virtual const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8005
virtual void SetAlloclockfunc(void(*)()) const
[Place holder for Mutex Lock] Provide the interpreter with a way to acquire a lock used to protect cr...
Definition: TCling.cxx:7033
virtual void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const
Definition: TCling.cxx:8431
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx)
Definition: TCling.cxx:8934
virtual Bool_t ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
Return true if the entity pointed to by 'declid' is declared in the context described by 'info'.
Definition: TCling.cxx:7589
std::set< size_t > fPayloads
Definition: TCling.h:109
virtual const char * ClassInfo_Name(ClassInfo_t *info) const
Definition: TCling.cxx:7868
Int_t UnloadLibraryMap(const char *library)
Unload library map entries coming from the specified library.
Definition: TCling.cxx:5538
virtual ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const
Definition: TCling.cxx:7971
TObjArray * fRootmapFiles
Definition: TCling.h:113
virtual void CallFunc_Delete(CallFunc_t *func) const
Definition: TCling.cxx:7301
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const
Definition: TCling.cxx:7610
virtual bool ClassInfo_IsLoaded(ClassInfo_t *info) const
Definition: TCling.cxx:7754
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition: TCling.h:134
virtual int ClassInfo_GetMethodNArg(ClassInfo_t *info, const char *method, const char *proto, Bool_t objectIsConst=false, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
Definition: TCling.cxx:7679
Int_t DeleteGlobal(void *obj)
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition: TCling.cxx:3381
virtual const char * GetCurrentMacroName() const
Return the file name of the currently interpreted file, included or not.
Definition: TCling.cxx:4986
virtual void TypeInfo_Delete(TypeInfo_t *tinfo) const
Definition: TCling.cxx:8745
virtual Bool_t LoadText(const char *text) const
Load the declarations from text into the interpreter.
Definition: TCling.cxx:7012
void GetInterpreterTypeName(const char *name, std::string &output, Bool_t full=kFALSE)
The 'name' is known to the interpreter, this function returns the internal version of this name (usua...
Definition: TCling.cxx:4723
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:8982
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const
Definition: TCling.cxx:7942
virtual int GetSecurityError() const
Interface to cling function.
Definition: TCling.cxx:6986
virtual UInt_t FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *) const
Return the number of required template arguments of the function template described by ft_info.
Definition: TCling.cxx:8282
void ResetGlobals()
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition: TCling.cxx:3338
virtual const char * ClassInfo_Title(ClassInfo_t *info) const
Definition: TCling.cxx:7876
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7963
virtual FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8237
void * GetInterfaceMethod(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return pointer to cling interface function for a method of a class with parameters params (params is ...
Definition: TCling.cxx:4537
virtual void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const
Definition: TCling.cxx:7641
virtual const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7987
virtual bool ClassInfo_IsEnum(const char *name) const
Definition: TCling.cxx:7729
Long_t ProcessLine(const char *line, EErrorCode *error=0)
Definition: TCling.cxx:2186
virtual void GetFunctionName(const clang::FunctionDecl *decl, std::string &name) const
Definition: TCling.cxx:8196
virtual void TypedefInfo_Delete(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8838
void SetGetline(const char *(*getlineFunc)(const char *prompt), void(*histaddFunc)(const char *line))
Set a getline function to call when input is needed.
Definition: TCling.cxx:3246
void UnloadClassMembers(TClass *cl, const clang::DeclContext *DC)
Helper function to go through the members of a class or namespace and unload them.
Definition: TCling.cxx:6558
Int_t fGlobalsListSerial
Definition: TCling.h:102
void RewindDictionary()
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition: TCling.cxx:3367
TString fSharedLibs
Definition: TCling.h:101
virtual const char * MapCppName(const char *) const
Interface to cling function.
Definition: TCling.cxx:7020
static void UpdateClassInfoWork(const char *name)
Definition: TCling.cxx:6453
virtual Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition: TCling.cxx:8352
void PrintIntro()
No-op; see TRint instead.
Definition: TCling.cxx:2350
virtual CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const
Definition: TCling.cxx:7375
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8132
Bool_t Declare(const char *code)
Declare code to the interpreter, without any of the interpreter actions that could trigger a re-inter...
Definition: TCling.cxx:2778
Int_t DeleteVariable(const char *name)
Undeclare obj called name.
Definition: TCling.cxx:3396
virtual int ClassInfo_Next(ClassInfo_t *info) const
Definition: TCling.cxx:7786
static void * fgSetOfSpecials
Definition: TCling.h:92
void AddIncludePath(const char *path)
Add the given path to the list of directories in which the interpreter looks for include files.
Definition: TCling.cxx:2359
virtual void CallFunc_SetArgArray(CallFunc_t *func, Long_t *paramArr, Int_t nparam) const
Definition: TCling.cxx:7480
virtual const char * MethodInfo_Name(MethodInfo_t *minfo) const
Definition: TCling.cxx:8554
void ClearFileBusy()
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition: TCling.cxx:2757
virtual const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8716
virtual Long_t ClassInfo_Property(ClassInfo_t *info) const
Definition: TCling.cxx:7826
Int_t fMore
Definition: TCling.h:96
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition: TCling.h:122
virtual int MethodInfo_Next(MethodInfo_t *minfo) const
Definition: TCling.cxx:8504
const char * TypeName(const char *typeDesc)
Return the absolute type of typeDesc.
Definition: TCling.cxx:5001
bool fIsShuttingDown
Definition: TCling.h:165
void SaveContext()
Save the current Cling state.
Definition: TCling.cxx:3457
std::set< TClass * > & GetModTClasses()
Definition: TCling.h:544
virtual bool TypeInfo_IsValid(TypeInfo_t *tinfo) const
Definition: TCling.cxx:8784
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)
Load library containing the specified class.
Definition: TCling.cxx:5680
TClingCallbacks * fClingCallbacks
Definition: TCling.h:127
TString GetMangledNameWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return the cling mangled name for a method of a class with a certain prototype, i....
Definition: TCling.cxx:4519
void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict)
Register classes that already existed prior to their dictionary loading and that already had a ClassI...
Definition: TCling.cxx:2117
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8092
void UpdateListOfGlobalFunctions()
No op: see TClingCallbacks (used to update the list of global functions)
Definition: TCling.cxx:3490
virtual const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const
Definition: TCling.cxx:8546
TString fIncludePath
Definition: TCling.h:103
virtual bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Long_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const
Definition: TCling.cxx:7770
virtual void * ClassInfo_New(ClassInfo_t *info) const
Definition: TCling.cxx:7794
virtual void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const
Definition: TCling.cxx:8775
Bool_t SetErrorMessages(Bool_t enable=kTRUE)
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition: TCling.cxx:6856
virtual const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8140
void TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:6724
virtual EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const
Definition: TCling.cxx:7745
virtual void CallFunc_Init(CallFunc_t *func) const
Definition: TCling.cxx:7398
virtual UInt_t FuncTempInfo_TemplateNargs(FuncTempInfo_t *) const
Return the maximum number of template arguments of the function template described by ft_info.
Definition: TCling.cxx:8271
TString GetMangledName(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return the cling mangled name for a method of a class with parameters params (params is a string of a...
Definition: TCling.cxx:4492
virtual void SetTempLevel(int val) const
Create / close a scope for temporaries.
Definition: TCling.cxx:7102
virtual DeclId_t GetDataMember(ClassInfo_t *cl, const char *name) const
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition: TCling.cxx:4302
void RegisterTemporary(const TInterpreterValue &value)
Definition: TCling.cxx:7145
virtual void LoadEnums(TListOfEnums &cl) const
Create list of pointers to enums for TClass cl.
Definition: TCling.cxx:3931
virtual void CallFunc_SetArg(CallFunc_t *func, Long_t param) const
Definition: TCling.cxx:7432
virtual Long_t GetExecByteCode() const
This routines used to return the address of the internal wrapper function (of the interpreter) that w...
Definition: TCling.cxx:6978
virtual void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const
Definition: TCling.cxx:8472
Int_t UnloadAllSharedLibraryMaps()
Unload the library map entries coming from all the loaded shared libraries.
Definition: TCling.cxx:5520
virtual void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const
Definition: TCling.cxx:7390
std::vector< cling::Value > * fTemporaries
Definition: TCling.h:121
virtual Long_t MethodInfo_Property(MethodInfo_t *minfo) const
Definition: TCling.cxx:8512
virtual std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const
Definition: TCling.cxx:7121
virtual Long_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8084
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6747
virtual TypedefInfo_t * TypedefInfo_Factory() const
Definition: TCling.cxx:8845
void UpdateListOfGlobals()
No op: see TClingCallbacks (used to update the list of globals)
Definition: TCling.cxx:3483
void ClearStack()
Delete existing temporary values.
Definition: TCling.cxx:2765
std::map< const cling::Transaction *, size_t > fTransactionHeadersMap
Definition: TCling.h:107
virtual int SetClassAutoparsing(int)
Enable/Disable the Autoparsing of headers.
Definition: TCling.cxx:7067
Bool_t fHeaderParsingOnDemand
Definition: TCling.h:159
Int_t RescanLibraryMap()
Scan again along the dynamic path for library maps.
Definition: TCling.cxx:5447
cling::Interpreter * fInterpreter
Definition: TCling.h:118
virtual int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8076
void Reset()
Pressing Ctrl+C should forward here.
Definition: TCling.cxx:3306
Int_t Load(const char *filenam, Bool_t system=kFALSE)
Load a library file in cling's memory.
Definition: TCling.cxx:3120
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient)
Visit all members over members, recursing over base classes.
Definition: TCling.cxx:2373
std::hash< std::string > fStringHashFunction
Definition: TCling.h:111
TEnv * fMapfile
Definition: TCling.h:105
const char * GetIncludePath()
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition: TCling.cxx:6870
virtual void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const
Definition: TCling.cxx:7633
Long_t ExecuteMacro(const char *filename, EErrorCode *error=0)
Execute a cling macro.
Definition: TCling.cxx:4926
virtual DeclId_t GetEnum(TClass *cl, const char *name) const
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition: TCling.cxx:4362
void GetFunctionOverloads(ClassInfo_t *cl, const char *funcname, std::vector< DeclId_t > &res) const
Insert overloads of name in cl to res.
Definition: TCling.cxx:4578
virtual void CallFunc_Exec(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7308
const char * GetSharedLibDeps(const char *lib)
Get the list a libraries on which the specified lib depends.
Definition: TCling.cxx:6815
virtual int DisplayIncludePath(FILE *fout) const
Interface to cling function.
Definition: TCling.cxx:6919
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition: TCling.cxx:3042
virtual void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const
Definition: TCling.cxx:410
void SaveGlobalsContext()
Save the current Cling state of global objects.
Definition: TCling.cxx:3470
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition: TCling.h:112
virtual Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8700
virtual const char * GetSTLIncludePath() const
Return the directory containing CINT's stl cintdlls.
Definition: TCling.cxx:6901
TString fRootmapLoadPath
Definition: TCling.h:104
Int_t LoadLibraryMap(const char *rootmapfile=0)
Load map between class and library.
Definition: TCling.cxx:5245
virtual std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8570
void Execute(const char *function, const char *params, int *error=0)
Execute a global function with arguments params.
Definition: TCling.cxx:4756
virtual const char * ClassInfo_FullName(ClassInfo_t *info) const
Definition: TCling.cxx:7858
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE)
Generate a TClass for the given class.
Definition: TCling.cxx:4082
virtual int TypeInfo_Size(TypeInfo_t *tinfo) const
Definition: TCling.cxx:8816
virtual int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8692
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition: TCling.h:123
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info) const
Definition: TCling.cxx:7687
virtual const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8910
Bool_t fIsAutoParsingSuspended
Definition: TCling.h:160
TClass * GetClass(const std::type_info &typeinfo, Bool_t load) const
Demangle the name (from the typeinfo) and then request the class via the usual name based interface (...
Definition: TCling.cxx:5634
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition: TCling.cxx:4402
Long_t ProcessLineAsynch(const char *line, EErrorCode *error=0)
Let cling process a command line asynch.
Definition: TCling.cxx:3168
virtual std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const
Get the scopes representing using declarations of namespace.
Definition: TCling.cxx:4014
Int_t SetClassSharedLibs(const char *cls, const char *libs)
Register the autoloading information for a class.
Definition: TCling.cxx:5600
virtual void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const
Definition: TCling.cxx:7703
virtual TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const
Definition: TCling.cxx:8768
Bool_t CheckClassTemplate(const char *name)
Return true if there is a class template by the given name ...
Definition: TCling.cxx:3887
char fPrompt[64]
Definition: TCling.h:98
void * fPrevLoadedDynLibInfo
Definition: TCling.h:125
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition: TCling.cxx:4052
virtual void SetDeclAttr(DeclId_t, const char *)
Definition: TCling.cxx:8159
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8100
virtual void ShutDown()
Definition: TCling.cxx:1422
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8116
virtual void CallFunc_SetArgs(CallFunc_t *func, const char *param) const
Definition: TCling.cxx:7488
Bool_t fAllowLibLoad
Definition: TCling.h:115
virtual const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7997
virtual void MethodInfo_Delete(MethodInfo_t *minfo) const
Interface to cling function.
Definition: TCling.cxx:8424
virtual const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const
Definition: TCling.cxx:8824
std::set< const char * > fParsedPayloadsAddresses
Definition: TCling.h:110
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE)
Checks if an entity with the specified name is defined in Cling.
Definition: TCling.cxx:3735
void EnableAutoLoading()
Enable the automatic loading of shared libraries when a class is used that is stored in a not yet loa...
Definition: TCling.cxx:2803
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition: TCling.cxx:6447
virtual void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7899
void ResetGlobalVar(void *obj)
Reset the Cling 'user' global objects/variables state to the state saved by the last call to TCling::...
Definition: TCling.cxx:3352
Bool_t IsLibraryLoaded(const char *libname) const
Definition: TCling.cxx:2832
virtual void Initialize()
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition: TCling.cxx:1417
virtual void * FindSym(const char *entry) const
Interface to cling function.
Definition: TCling.cxx:6948
virtual Long_t CallFunc_ExecInt(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7343
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const
Definition: TCling.cxx:8068
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE)
Set pointer to the TClingClassInfo in TClass.
Definition: TCling.cxx:3611
Long_t ProcessLineSynch(const char *line, EErrorCode *error=0)
Let cling process a command line synchronously, i.e we are waiting it will be finished.
Definition: TCling.cxx:3177
virtual int TypeInfo_RefType(TypeInfo_t *) const
Definition: TCling.cxx:8808
void LoadMacro(const char *filename, EErrorCode *error=0)
Load a macro file in cling's memory.
Definition: TCling.cxx:3160
std::set< size_t > fLookedUpClasses
Definition: TCling.h:108
virtual void CallFunc_ResetArg(CallFunc_t *func) const
Definition: TCling.cxx:7424
virtual Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7351
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:7979
void ResetAll()
Reset the Cling state to its initial state.
Definition: TCling.cxx:3322
virtual void ClassInfo_Delete(ClassInfo_t *info) const
Definition: TCling.cxx:7618
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo=0) const
Definition: TCling.cxx:8033
virtual Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7359
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:5814
virtual const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8926
void CreateListOfBaseClasses(TClass *cl) const
Create list of pointers to base class(es) for TClass cl.
Definition: TCling.cxx:3907
void RecursiveRemove(TObject *obj)
Delete object from cling symbol table so it can not be used anymore.
Definition: TCling.cxx:3281
virtual MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:8676
void UpdateListsOnUnloaded(const cling::Transaction &T)
Definition: TCling.cxx:6611
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition: TCling.cxx:6389
virtual const char * ClassInfo_FileName(ClassInfo_t *info) const
Definition: TCling.cxx:7850
virtual void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:7332
DeclId_t GetFunctionTemplate(ClassInfo_t *cl, const char *funcname)
Return pointer to cling interface function for a method of a class with a certain name.
Definition: TCling.cxx:4700
virtual int MethodInfo_NArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8488
virtual FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8248
void * fAutoLoadCallBack
Definition: TCling.h:135
virtual int TypedefInfo_Size(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8902
virtual const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8918
virtual void CallFunc_SetFuncProto(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *proto, Long_t *Offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
Interface to cling function.
Definition: TCling.cxx:7523
virtual int DisplayClass(FILE *fout, const char *name, int base, int start) const
Definition: TCling.cxx:6910
const char * GetClassSharedLibs(const char *cls)
Get the list of shared libraries containing the code for class cls.
Definition: TCling.cxx:6773
Bool_t IsErrorMessagesEnabled() const
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition: TCling.cxx:6842
ULong64_t fTransactionCount
Definition: TCling.h:136
virtual Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const
Check validity of a FuncTempInfo_t.
Definition: TCling.cxx:8259
virtual BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const
Definition: TCling.cxx:7906
virtual bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:8878
virtual MethodInfo_t * MethodInfo_Factory() const
Definition: TCling.cxx:8439
Int_t AutoParse(const char *cls)
Parse the headers relative to the class Returns 1 in case of success, 0 in case of failure.
Definition: TCling.cxx:5956
virtual EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const
Definition: TCling.cxx:8600
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition: TCling.cxx:4633
virtual TypeInfo_t * TypeInfo_Factory() const
Definition: TCling.cxx:8752
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition: TCling.h:106
virtual int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8496
Int_t GenerateDictionary(const char *classes, const char *includes="", const char *options=0)
Generate the dictionary for the C++ classes listed in the first argument (in a semi-colon separated l...
Definition: TCling.cxx:4254
virtual void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Long_t *Offset) const
Definition: TCling.cxx:7496
void CreateListOfMethods(TClass *cl) const
Create list of pointers to methods for TClass cl.
Definition: TCling.cxx:4034
void UpdateListOfMethods(TClass *cl) const
Update the list of pointers to method for TClass cl This is now a nop.
Definition: TCling.cxx:4043
cling::MetaProcessor * fMetaProcessor
Definition: TCling.h:119
virtual int ClassInfo_Size(ClassInfo_t *info) const
Definition: TCling.cxx:7834
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition: TCling.cxx:6462
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6753
Collection abstract base class.
Definition: TCollection.h:63
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add(TObject *obj)=0
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
virtual bool Update(DataMemberInfo_t *info)
Update the TFunction to reflect the new info.
Bool_t IsPersistent() const
Definition: TDataMember.h:89
Bool_t IsValid()
Return true if this data member object is pointing to a currently loaded data member.
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
virtual TList * GetListOfKeys() const
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:144
The TEnumConstant class implements the constants of the enum type.
Definition: TEnumConstant.h:29
The TEnum class implements the enum type.
Definition: TEnum.h:33
const TSeqCollection * GetConstants() const
Definition: TEnum.h:61
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition: TEnum.cxx:143
DeclId_t GetDeclId() const
Definition: TEnum.cxx:116
@ kNone
Definition: TEnum.h:47
@ kAutoload
Definition: TEnum.h:48
Definition: TEnv.h:87
const char * GetValue() const
Definition: TEnv.h:111
const char * GetName() const
Returns name of object.
Definition: TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition: TEnv.h:125
THashList * GetTable() const
Definition: TEnv.h:141
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:146
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:592
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition: TEnv.cxx:547
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:736
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
Dictionary for function template This class describes one single function template.
virtual bool Update(FuncTempInfo_t *info)
Update the TFunctionTemplate to reflect the new info.
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:28
MethodInfo_t * fInfo
Definition: TFunction.h:34
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 * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:262
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:378
THashTable implements a hash table to store TObject's.
Definition: THashTable.h:35
virtual const void * GetValAddr() const =0
This class defines an abstract interface to a generic command line interpreter.
Definition: TInterpreter.h:60
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
Definition: TInterpreter.h:132
virtual Bool_t IsLoaded(const char *filename) const =0
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
Definition: TInterpreter.h:133
TDictionary::DeclId_t DeclId_t
Definition: TInterpreter.h:281
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TDictionary::DeclId_t DeclId_t
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
void Unload()
Mark 'all func' as being unloaded.
virtual TObject * FindObject(const char *name) const
Specialize FindObject to do search for the a data member just by name or create it if its not already...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
Definition: TListOfEnums.h:33
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TDictionary::DeclId_t DeclId_t
Definition: TListOfEnums.h:59
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
Definition: TListOfEnums.h:62
void Unload()
Mark 'all func' as being unloaded.
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
virtual TObject * FindObject(const char *name) const
Specialize FindObject to do search for the a function just by name or create it if its not already in...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
void Unload()
Mark 'all func' as being unloaded.
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
virtual TObject * FindObject(const TObject *obj) const
Find object using its hash value (returned by its Hash() member).
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
TDictionary::DeclId_t DeclId_t
void Unload()
Mark 'all func' as being unloaded.
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:31
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
Definition: TMethodArg.cxx:75
const char * GetDefault() const
Get default value of method argument.
Definition: TMethodArg.cxx:58
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition: TMethod.cxx:306
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TNamed()
Definition: TNamed.h:36
TString fName
Definition: TNamed.h:32
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Definition: TObjArray.cxx:386
void Add(TObject *obj)
Definition: TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:333
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:718
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Collectable string class.
Definition: TObjString.h:28
TString & String()
Definition: TObjString.h:48
Mother of all ROOT objects.
Definition: TObject.h:37
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition: TObject.h:133
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
void MakeZombie()
Definition: TObject.h:49
void ResetBit(UInt_t f)
Definition: TObject.h:171
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Persistent version of a TClass.
Definition: TProtoClass.h:35
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition: TROOT.cxx:3007
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2767
virtual ~TROOT()
Clean up and free resources used by ROOT (files, network sockets, shared memory segments,...
Definition: TROOT.cxx:903
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition: TROOT.cxx:2917
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:3028
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition: TROOT.cxx:2927
Int_t LastIndex() const
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
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:2311
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1013
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:852
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:843
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1652
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3894
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4163
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1061
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1526
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:894
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1843
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:1388
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1071
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:1286
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:860
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2532
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:941
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1782
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:446
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:2873
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:878
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1536
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:741
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:50
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TText * text
TLine * line
Type
enumeration specifying the integration types.
const Int_t n
Definition: legend1.C:16
Double_t ex[n]
Definition: legend1.C:17
TF1 * f1
Definition: legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
#define H(x, y, z)
TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
Definition: Cppyy.cxx:747
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:387
static double P[]
static double A[]
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:151
RVec< T > Filter(const RVec< T > &v, F &&f)
Create a new collection with the elements passing the filter expressed by the predicate.
Definition: RVec.hxx:936
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
Definition: TDictionary.h:152
@ kExactMatch
Definition: TDictionary.h:153
V GetOffset(E val1, E val2, V iso)
RooArgSet S(const RooAbsArg &v1)
bool IsStdArray(std::string_view name)
Definition: TClassEdit.h:186
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
std::string InsertStd(const char *tname)
bool SplitFunction(std::string_view decl, FunctionSplitInfo &result)
Split a function declaration into its different parts.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
Definition: TClassEdit.cxx:863
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'.
Definition: TClassEdit.cxx:897
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:144
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:205
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.
Definition: TClassEdit.cxx:984
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
Definition: TClassEdit.cxx:821
@ kDropTrailStar
Definition: TClassEdit.h:76
@ kDropStlDefault
Definition: TClassEdit.h:81
EComplexType GetComplexType(const char *)
Definition: TClassEdit.cxx:110
static constexpr double s
static constexpr double ns
static constexpr double L
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Definition: file.py:1
const char * Name
Definition: TXMLSetup.cxx:66
const char * Value
Definition: TXMLSetup.cxx:72
Int_t fMode
Definition: TSystem.h:128
Long_t fMemVirtual
Definition: TSystem.h:197
Long_t fMemResident
Definition: TSystem.h:196
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition: ClingRAII.h:22
State as returned by GetStateDelta() that can be passed to Restore()
Result of splitting a function declaration into fReturnType fScopeName::fFunctionName<fFunctionTempla...
Definition: TClassEdit.h:231
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
Definition: TClassEdit.h:236
std::vector< std::string > fElements
Definition: TClassEdit.h:140
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
Definition: TClassEdit.cxx:223
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
static void output(int code)
Definition: gifencode.c:226