63 #include "RConfigure.h"
64 #include "compiledata.h"
65 #include "TClingUtils.h"
81 #include "clang/AST/ASTContext.h"
82 #include "clang/AST/Decl.h"
83 #include "clang/AST/DeclarationName.h"
84 #include "clang/AST/GlobalDecl.h"
85 #include "clang/AST/RecordLayout.h"
86 #include "clang/AST/DeclVisitor.h"
87 #include "clang/AST/RecursiveASTVisitor.h"
88 #include "clang/AST/Type.h"
89 #include "clang/Basic/SourceLocation.h"
90 #include "clang/Basic/Specifiers.h"
91 #include "clang/Basic/TargetInfo.h"
92 #include "clang/CodeGen/ModuleBuilder.h"
93 #include "clang/Frontend/CompilerInstance.h"
94 #include "clang/Frontend/FrontendDiagnostic.h"
95 #include "clang/Lex/HeaderSearch.h"
96 #include "clang/Lex/Preprocessor.h"
97 #include "clang/Lex/PreprocessorOptions.h"
98 #include "clang/Sema/Lookup.h"
99 #include "clang/Sema/Sema.h"
100 #include "clang/Parse/Parser.h"
102 #include "cling/Interpreter/ClangInternalState.h"
103 #include "cling/Interpreter/DynamicLibraryManager.h"
104 #include "cling/Interpreter/Interpreter.h"
105 #include "cling/Interpreter/LookupHelper.h"
106 #include "cling/Interpreter/Value.h"
107 #include "cling/Interpreter/Transaction.h"
108 #include "cling/MetaProcessor/MetaProcessor.h"
109 #include "cling/Utils/AST.h"
110 #include "cling/Utils/ParserStateRAII.h"
111 #include "cling/Utils/SourceNormalization.h"
112 #include "cling/Interpreter/Exception.h"
114 #include "llvm/IR/GlobalValue.h"
115 #include "llvm/IR/Module.h"
117 #include "llvm/Support/DynamicLibrary.h"
118 #include "llvm/Support/raw_ostream.h"
119 #include "llvm/Support/Path.h"
120 #include "llvm/Support/Process.h"
121 #include "llvm/Object/ELFObjectFile.h"
122 #include "llvm/Object/ObjectFile.h"
123 #include "llvm/Object/SymbolicFile.h"
124 #include "llvm/Support/FileSystem.h"
138 #include <unordered_map>
141 #include <functional>
145 #define R__DLLEXPORT __attribute__ ((visibility ("default")))
146 #include <sys/stat.h>
153 #include <mach-o/dyld.h>
154 #include <mach-o/loader.h>
161 #if defined(__CYGWIN__)
162 #include <sys/cygwin.h>
163 #define HMODULE void *
165 __declspec(dllimport) void * __stdcall GetCurrentProcess();
166 __declspec(dllimport)
bool __stdcall EnumProcessModules(
void *,
void **,
unsigned long,
unsigned long *);
167 __declspec(dllimport)
unsigned long __stdcall GetModuleFileNameExW(
void *,
void *,
wchar_t *,
unsigned long);
172 #if defined(_MSC_VER)
174 # define STDIN_FILENO 0
176 #ifndef STDOUT_FILENO
177 # define STDOUT_FILENO 1
179 #ifndef STDERR_FILENO
180 # define STDERR_FILENO 2
189 #undef GetModuleFileName
190 #define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
191 #define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
192 #define dlopen(library_name, flags) ::LoadLibraryA(library_name)
193 #define dlclose(library) ::FreeLibrary((HMODULE)library)
194 #define R__DLLEXPORT __declspec(dllexport)
202 class TCling_UnloadMarker {
204 ~TCling_UnloadMarker() {
205 if (ROOT::Internal::gROOTLocal) {
206 ROOT::Internal::gROOTLocal->~TROOT();
210 static TCling_UnloadMarker gTClingUnloadMarker;
218 R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
219 return D->getDeclContext();
221 R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
224 R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
225 return llvm::dyn_cast<clang::RecordDecl>(DC);
227 R__DLLEXPORT
void TCling__DEBUG__dump(clang::DeclContext* DC) {
228 return DC->dumpDeclContext();
230 R__DLLEXPORT
void TCling__DEBUG__dump(clang::Decl* D) {
233 R__DLLEXPORT
void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
236 R__DLLEXPORT
void TCling__DEBUG__decl_dump(
void* D) {
237 return ((clang::Decl*)D)->dump();
239 R__DLLEXPORT
void TCling__DEBUG__printName(clang::Decl* D) {
240 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
243 llvm::raw_string_ostream OS(name);
244 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
247 printf(
"%s\n", name.c_str());
254 R__DLLEXPORT
bool TCling__TEST_isInvalidDecl(clang::Decl* D) {
255 return D->isInvalidDecl();
257 R__DLLEXPORT
bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
258 TClingClassInfo *info( (TClingClassInfo*) input);
259 assert(info && info->IsValid());
260 return info->GetDecl()->isInvalidDecl();
264 using namespace clang;
265 using namespace ROOT;
268 static const std::string gInterpreterClassDef = R
"ICF(
#undef ClassDef
#define ClassDef(name, id) \
_ClassDefInterp_(name,id,virtual,) \
static int DeclFileLine() { return __LINE__; }
#undef ClassDefNV
#define ClassDefNV(name, id) \
_ClassDefInterp_(name,id,,) \
static int DeclFileLine() { return __LINE__; }
#undef ClassDefOverride
#define ClassDefOverride(name, id) \
_ClassDefInterp_(name,id,,override) \
static int DeclFileLine() { return __LINE__; }
)ICF";
270 static const std::string gNonInterpreterClassDef = R
"ICF(
#define __ROOTCLING__ 1
#undef ClassDef
#define ClassDef(name,id) \
_ClassDefOutline_(name,id,virtual,) \
static int DeclFileLine() { return __LINE__; }
#undef ClassDefNV
#define ClassDefNV(name, id)\
_ClassDefOutline_(name,id,,)\
static int DeclFileLine() { return __LINE__; }
#undef ClassDefOverride
#define ClassDefOverride(name, id)\
_ClassDefOutline_(name,id,,override)\
static int DeclFileLine() { return __LINE__; }
)ICF";
273 static const std::string gClassDefInterpMacro = R
"ICF(
#include "TError.h"
#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
private: \
public: \
static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
static const char *Class_Name() { return #name; } \
virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
static Version_t Class_Version() { return id; } \
static TClass *Dictionary() { return 0; } \
virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
static const char *DeclFileName() { return __FILE__; } \
static int ImplFileLine() { return 0; } \
static const char *ImplFileName() { return __FILE__; }
)ICF";
275 R__EXTERN int optind;
284 void TCling__PrintStackTrace() {
285 gSystem->StackTrace();
291 extern "C" void TCling__RestoreInterpreterMutex(
void *delta)
293 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
301 extern "C" bool TCling__LibraryLoadingFailed(
const std::string& errmessage,
const std::string& libStem,
bool permanent,
bool resolved)
303 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
310 extern "C" void *TCling__ResetInterpreterMutex()
312 return ((TCling*)gCling)->RewindInterpreterMutex();
318 extern "C" void *TCling__LockCompilationDuringUserCodeExecution()
320 if (gInterpreterMutex) {
321 gInterpreterMutex->Lock();
329 extern "C" void TCling__UnlockCompilationDuringUserCodeExecution(
void* )
331 if (gInterpreterMutex) {
332 gInterpreterMutex->UnLock();
339 static void TCling__UpdateClassInfo(
const NamedDecl* TD)
341 static Bool_t entered = kFALSE;
342 static vector<const NamedDecl*> updateList;
345 if (entered) topLevel = kFALSE;
351 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
360 updateList.push_back(TD);
363 while (!updateList.empty()) {
364 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
365 updateList.pop_back();
371 void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl)
const {
372 const clang::Decl* D =
static_cast<const clang::Decl*
>(enumObj->GetDeclId());
373 if(
const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
375 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
376 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
378 std::string constbuf;
379 if (
const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
380 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
381 llvm::raw_string_ostream stream(constbuf);
383 Policy.AnonymousTagLocations =
false;
384 (END)->getNameForDiagnostic(stream, Policy,
false);
386 const char* constantName = constbuf.c_str();
390 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
391 if (valAPSInt.isSigned()) {
392 value = valAPSInt.getSExtValue();
394 value = valAPSInt.getZExtValue();
398 TEnumConstant* enumConstant =
nullptr;
399 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
400 TClingDataMemberInfo* tcDmInfo =
new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
401 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
402 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
403 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
405 enumConstant =
new TEnumConstant(dmInfo, constantName, value, enumObj);
410 TCollection* globals = gROOT->GetListOfGlobals(
false);
411 if (!globals->FindObject(constantName)) {
412 globals->Add(enumConstant);
419 TEnum* TCling::CreateEnum(
void *VD, TClass *cl)
const
425 const clang::Decl* D =
static_cast<const clang::Decl*
>(VD);
427 if (
const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
429 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
430 llvm::raw_string_ostream stream(buf);
432 Policy.AnonymousTagLocations =
false;
433 ED->getNameForDiagnostic(stream, Policy,
false);
439 const char* name = buf.c_str();
440 enumType =
new TEnum(name, VD, cl);
441 UpdateEnumConstants(enumType, cl);
446 void TCling::HandleNewDecl(
const void* DV,
bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
450 const clang::Decl* D =
static_cast<const clang::Decl*
>(DV);
452 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
453 && !dyn_cast<clang::RecordDecl>(D))
return;
455 if (isa<clang::FunctionDecl>(D->getDeclContext())
456 || isa<clang::TagDecl>(D->getDeclContext()))
460 if (
const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
461 if (RD->getDescribedClassTemplate())
463 }
else if (
const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
464 if (FD->getDescribedFunctionTemplate())
468 if (
const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
469 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
470 TCling__UpdateClassInfo(TD);
472 else if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
474 if (
const TagDecl *TD = dyn_cast<TagDecl>(D)) {
477 TCling__UpdateClassInfo(TD);
478 }
else if (
const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
479 TCling__UpdateClassInfo(NSD);
483 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
487 if (isa<EnumDecl>(ND))
492 if (!(isa<VarDecl>(ND)))
496 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
500 gROOT->GetListOfGlobals()->Add(
new TGlobal((DataMemberInfo_t *)
501 new TClingDataMemberInfo(GetInterpreterImpl(),
502 cast<ValueDecl>(ND), 0)));
507 void TCling__GetNormalizedContext(
const ROOT::TMetaUtils::TNormalizedCtxt*& normCtxt)
510 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
514 void TCling__UpdateListsOnCommitted(
const cling::Transaction &T, cling::Interpreter*) {
515 ((TCling*)gCling)->UpdateListsOnCommitted(T);
519 void TCling__UpdateListsOnUnloaded(
const cling::Transaction &T) {
520 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
524 void TCling__InvalidateGlobal(
const clang::Decl *D) {
525 ((TCling*)gCling)->InvalidateGlobal(D);
529 void TCling__TransactionRollback(
const cling::Transaction &T) {
530 ((TCling*)gCling)->TransactionRollback(T);
533 extern "C" void TCling__LibraryLoadedRTTI(
const void* dyLibHandle,
534 const char* canonicalName) {
535 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
538 extern "C" void TCling__RegisterRdictForLoadPCM(
const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
540 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
543 extern "C" void TCling__LibraryUnloadedRTTI(
const void* dyLibHandle,
544 const char* canonicalName) {
545 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
550 TObject* TCling__GetObjectAddress(
const char *Name,
void *&LookupCtx) {
551 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
554 extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
555 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
558 extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(
void* interpLibHandle,
561 cling::DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(interpLibHandle);
562 return new TCling(
"C++",
"cling C++ Interpreter", argv);
565 extern "C" R__DLLEXPORT
void DestroyInterpreter(TInterpreter *interp)
572 extern "C" int TCling__AutoLoadCallback(
const char* className)
574 return ((TCling*)gCling)->AutoLoad(className);
577 extern "C" int TCling__AutoParseCallback(
const char* className)
579 return ((TCling*)gCling)->AutoParse(className);
582 extern "C" const char* TCling__GetClassSharedLibs(
const char* className)
584 return ((TCling*)gCling)->GetClassSharedLibs(className);
588 extern "C" int TCling__IsAutoLoadNamespaceCandidate(
const clang::NamespaceDecl* nsDecl)
590 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
593 extern "C" int TCling__CompileMacro(
const char *fileName,
const char *options)
595 string file(fileName);
597 return gSystem->CompileMacro(file.c_str(), opt.c_str());
600 extern "C" void TCling__SplitAclicMode(
const char* fileName,
string &mode,
601 string &args,
string &io,
string &fname)
603 string file(fileName);
604 TString f, amode, arguments, aclicio;
605 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
606 mode = amode.Data(); args = arguments.Data();
607 io = aclicio.Data(); fname = f.Data();
611 extern "C" void TCling__FindLoadedLibraries(std::vector<std::pair<uint32_t, std::string>> &sLibraries,
612 std::vector<std::string> &sPaths,
613 cling::Interpreter &interpreter,
bool searchSystem);
622 char *__unDName(
char *demangled,
const char *mangled,
int out_len,
623 void * (* pAlloc )(
size_t),
void (* pFree )(
void *),
624 unsigned short int flags);
634 static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
636 using namespace clang;
637 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
638 return FindTemplateInNamespace(*nsd->decls_begin());
641 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
651 void* llvmLazyFunctionCreator(
const std::string& mangled_name)
653 return ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
661 int TCling_GenerateDictionary(
const std::vector<std::string> &classes,
662 const std::vector<std::string> &headers,
663 const std::vector<std::string> &fwdDecls,
664 const std::vector<std::string> &unknown)
670 if (classes.empty()) {
674 const std::string& className = classes[0];
676 TString fileName =
"AutoDict_";
677 std::string::const_iterator sIt;
678 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
679 if (*sIt ==
'<' || *sIt ==
'>' ||
680 *sIt ==
' ' || *sIt ==
'*' ||
681 *sIt ==
',' || *sIt ==
'&' ||
689 if (classes.size() > 1) {
691 std::vector<std::string>::const_iterator it = classes.begin();
692 while ((++it) != classes.end()) {
693 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
694 chk = chk * 3 + it->at(cursor);
697 fileName += TString::Format(
"_%u", chk);
700 if (gSystem->AccessPathName(fileName) != 0) {
707 static const std::set<std::string> sSTLTypes {
708 "vector",
"list",
"forward_list",
"deque",
"map",
"unordered_map",
"multimap",
709 "unordered_multimap",
"set",
"unordered_set",
"multiset",
"unordered_multiset",
710 "queue",
"priority_queue",
"stack",
"iterator"};
711 std::vector<std::string>::const_iterator it;
712 std::string fileContent(
"");
713 for (it = headers.begin(); it != headers.end(); ++it) {
714 fileContent +=
"#include \"" + *it +
"\"\n";
716 for (it = unknown.begin(); it != unknown.end(); ++it) {
717 TClass* cl = TClass::GetClass(it->c_str());
718 if (cl && cl->GetDeclFileName()) {
719 TString header(gSystem->BaseName(cl->GetDeclFileName()));
720 TString dir(gSystem->DirName(cl->GetDeclFileName()));
721 TString dirbase(gSystem->BaseName(dir));
722 while (dirbase.Length() && dirbase !=
"."
723 && dirbase !=
"include" && dirbase !=
"inc"
724 && dirbase !=
"prec_stl") {
725 gSystem->PrependPathName(dirbase, header);
726 dir = gSystem->DirName(dir);
728 fileContent += TString(
"#include \"") + header +
"\"\n";
731 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
732 fileContent +=
"class " + *it +
";\n";
734 fileContent +=
"#ifdef __CINT__ \n";
735 fileContent +=
"#pragma link C++ nestedclasses;\n";
736 fileContent +=
"#pragma link C++ nestedtypedefs;\n";
737 for (it = classes.begin(); it != classes.end(); ++it) {
739 size_t posTemplate = n.find(
'<');
740 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
741 if (posTemplate != std::string::npos) {
742 n.erase(posTemplate, std::string::npos);
743 if (n.compare(0, 5,
"std::") == 0) {
746 iSTLType = sSTLTypes.find(n);
748 fileContent +=
"#pragma link C++ class ";
749 fileContent += *it +
"+;\n" ;
750 fileContent +=
"#pragma link C++ class ";
751 if (iSTLType != sSTLTypes.end()) {
755 fileContent += *it +
"::*;\n" ;
760 fileContent += *it +
"::*+;\n" ;
763 fileContent +=
"#endif\n";
767 filePointer = fopen(fileName,
"w");
768 if (filePointer == NULL) {
774 fprintf(filePointer,
"%s", fileContent.c_str());
778 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
779 gErrorIgnoreLevel = kWarning;
780 Int_t ret = gSystem->CompileMacro(fileName,
"k");
781 gErrorIgnoreLevel = oldErrorIgnoreLevel;
789 int TCling_GenerateDictionary(
const std::string& className,
790 const std::vector<std::string> &headers,
791 const std::vector<std::string> &fwdDecls,
792 const std::vector<std::string> &unknown)
798 std::vector<std::string> classes;
799 classes.push_back(className);
800 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
810 const char* fantomline =
"TRint::EndOfLineAction();";
817 void* TCling::fgSetOfSpecials = 0;
827 void exceptionErrorHandler(
void * ,
828 const std::string& reason,
830 throw std::runtime_error(std::string(
">>> Interpreter compilation error:\n") + reason);
844 class clangDiagSuppr {
846 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
847 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
848 fDiagEngine.setIgnoreAllWarnings(
true);
852 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
855 clang::DiagnosticsEngine& fDiagEngine;
863 bool TClingLookupHelper__AutoParse(
const char *cname)
865 return gCling->AutoParse(cname);
872 bool TClingLookupHelper__ExistingTypeCheck(
const std::string &tname,
877 unsigned long offset = 0;
878 if (strncmp(tname.c_str(),
"const ", 6) == 0) {
881 unsigned long end = tname.length();
882 while( end && (tname[end-1]==
'&' || tname[end-1]==
'*' || tname[end-1]==
']') ) {
883 if ( tname[end-1]==
']' ) {
885 while ( end && tname[end-1]!=
'[' ) --end;
889 std::string innerbuf;
891 if (end != tname.length()) {
892 innerbuf = tname.substr(offset,end-offset);
893 inner = innerbuf.c_str();
895 inner = tname.c_str()+offset;
899 if (gROOT->GetListOfClasses()->FindObject(inner)
900 || TClassTable::Check(inner,result) ) {
905 THashTable *typeTable =
dynamic_cast<THashTable*
>( gROOT->GetListOfTypes() );
906 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
909 const char *newname = type->GetFullTypeName();
910 if (type->GetType() == kLong64_t) {
911 newname =
"Long64_t";
912 }
else if (type->GetType() == kULong64_t) {
913 newname =
"ULong64_t";
915 if (strcmp(inner,newname) == 0) {
918 if (offset) result =
"const ";
920 if ( end != tname.length() ) {
921 result += tname.substr(end,tname.length()-end);
923 if (result == tname) result.clear();
928 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
929 if (lastPos != inner)
933 const auto enName = lastPos;
934 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) /
sizeof(decltype(*lastPos)) - 2;
935 char *scopeName =
new char[scopeNameSize + 1];
936 strncpy(scopeName, inner, scopeNameSize);
937 scopeName[scopeNameSize] =
'\0';
939 if (
auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
940 auto enumTable =
dynamic_cast<const THashList *
>(scope->GetListOfEnums(
false));
941 if (enumTable && enumTable->THashList::FindObject(enName))
return true;
944 else if (
auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
945 auto listOfEnums = scope->GetListOfEnums();
947 auto enumTable =
dynamic_cast<const THashList *
>(listOfEnums);
948 if (enumTable && enumTable->THashList::FindObject(enName))
return true;
955 auto enumTable =
dynamic_cast<const THashList *
>(gROOT->GetListOfEnums());
956 if (enumTable && enumTable->THashList::FindObject(inner))
return true;
959 if (gCling->GetClassSharedLibs(inner))
970 TCling::TUniqueString::TUniqueString(Long64_t size)
972 fContent.reserve(size);
977 inline const char *TCling::TUniqueString::Data()
979 return fContent.c_str();
985 inline bool TCling::TUniqueString::Append(
const std::string& str)
987 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
994 std::string TCling::ToString(
const char* type,
void* obj)
996 return fInterpreter->toString(type, obj);
1001 static bool LoadModule(
const std::string &ModuleName, cling::Interpreter &interp)
1010 std::string currentDir = gSystem->WorkingDirectory();
1011 assert(!currentDir.empty());
1012 gCling->RegisterPrebuiltModulePath(currentDir);
1013 return interp.loadModule(ModuleName,
true);
1019 static void LoadModules(
const std::vector<std::string> &modules, cling::Interpreter &interp)
1021 for (
const auto &modName : modules)
1022 LoadModule(modName, interp);
1025 static bool IsFromRootCling() {
1027 const static bool foundSymbol = dlsym(RTLD_DEFAULT,
"usedToIdentifyRootClingByDlSym");
1031 static std::string GetModuleNameAsString(clang::Module *M,
const clang::Preprocessor &PP)
1033 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1035 std::string ModuleFileName;
1036 if (!HSOpts.PrebuiltModulePaths.empty())
1038 ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(M->Name,
"",
true);
1039 if (ModuleFileName.empty())
return "";
1041 std::string ModuleName = llvm::sys::path::filename(ModuleFileName);
1043 return std::string(llvm::sys::path::stem(ModuleName));
1046 static void RegisterCxxModules(cling::Interpreter &clingInterp)
1048 if (!clingInterp.getCI()->getLangOpts().Modules)
1054 LoadModule(
"Darwin", clingInterp);
1056 LoadModule(
"libc", clingInterp);
1058 LoadModule(
"std", clingInterp);
1060 LoadModule(
"_Builtin_intrinsics", clingInterp);
1064 std::vector<std::string> CoreModules = {
"ROOT_Foundation_C",
1067 "ROOT_Foundation_Stage1_NoRTTI",
1072 static constexpr std::array<const char *, 3> ExcludeModules = {
1073 {
"Rtools",
"RSQLite",
"RInterface"}};
1075 LoadModules(CoreModules, clingInterp);
1078 if (!IsFromRootCling()) {
1080 clang::CompilerInstance &CI = *clingInterp.getCI();
1081 clang::ModuleMap &moduleMap = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap();
1082 clang::Preprocessor &PP = CI.getPreprocessor();
1083 std::vector<std::string> ModulesPreloaded;
1084 for (
auto I = moduleMap.module_begin(), E = moduleMap.module_end(); I != E; ++I) {
1085 clang::Module *M = I->second;
1088 std::string ModuleName = GetModuleNameAsString(M, PP);
1089 if (!ModuleName.empty() &&
1090 std::find(CoreModules.begin(), CoreModules.end(), ModuleName) == CoreModules.end() &&
1091 std::find(ExcludeModules.begin(), ExcludeModules.end(), ModuleName) ==
1092 ExcludeModules.end()) {
1093 if (M->IsSystem && !M->IsMissingRequirement)
1094 LoadModule(ModuleName, clingInterp);
1095 else if (!M->IsSystem && !M->IsMissingRequirement)
1096 ModulesPreloaded.push_back(ModuleName);
1099 LoadModules(ModulesPreloaded, clingInterp);
1103 assert(clingInterp.getMacro(
"gROOT") &&
"Couldn't load gROOT macro?");
1111 clingInterp.declare(
"#ifdef I\n #undef I\n #endif\n");
1115 clingInterp.declare(
"#ifdef complex\n #undef complex\n #endif\n");
1119 clingInterp.declare(
"#ifdef PI\n #undef PI\n #endif\n");
1120 clingInterp.declare(
"#ifdef ERROR\n #undef ERROR\n #endif\n");
1123 static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1125 std::string PreIncludes;
1126 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1131 if (IsFromRootCling()) {
1132 PreIncludes +=
"#include \"RtypesCore.h\"\n";
1135 PreIncludes +=
"#include \"Rtypes.h\"\n";
1137 PreIncludes += gClassDefInterpMacro +
"\n"
1138 + gInterpreterClassDef +
"\n"
1140 "#define ClassImp(X);\n";
1143 PreIncludes +=
"#include <string>\n";
1147 PreIncludes +=
"#include <cassert>\n";
1148 PreIncludes +=
"using namespace std;\n";
1149 clingInterp.declare(PreIncludes);
1157 TCling::TCling(
const char *name,
const char *title,
const char*
const argv[])
1158 : TInterpreter(name, title), fMore(0), fGlobalsListSerial(-1), fMapfile(nullptr),
1159 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(0),
1160 fPrevLoadedDynLibInfo(0), fClingCallbacks(0), fAutoLoadCallBack(0),
1161 fTransactionCount(0), fHeaderParsingOnDemand(true), fIsAutoParsingSuspended(kFALSE)
1164 const bool fromRootCling = IsFromRootCling();
1166 fCxxModulesEnabled =
false;
1167 #ifdef R__USE_CXXMODULES
1168 fCxxModulesEnabled =
true;
1171 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1173 fTemporaries =
new std::vector<cling::Value>();
1175 std::vector<std::string> clingArgsStorage;
1176 clingArgsStorage.push_back(
"cling4root");
1177 for (
const char*
const* arg = argv; *arg; ++arg)
1178 clingArgsStorage.push_back(*arg);
1181 if (!fromRootCling) {
1182 ROOT::TMetaUtils::SetPathsForRelocatability(clingArgsStorage);
1185 std::string interpInclude(TROOT::GetEtcDir().Data());
1186 clingArgsStorage.push_back(
"-I" + interpInclude);
1189 clingArgsStorage.push_back(
"-I" + interpInclude +
"/cling");
1192 clingArgsStorage.push_back(std::string((
"-I" + TROOT::GetIncludeDir()).Data()));
1199 if (!fCxxModulesEnabled) {
1200 std::string pchFilename = interpInclude +
"/allDict.cxx.pch";
1201 if (gSystem->Getenv(
"ROOT_PCH")) {
1202 pchFilename = gSystem->Getenv(
"ROOT_PCH");
1205 clingArgsStorage.push_back(
"-include-pch");
1206 clingArgsStorage.push_back(pchFilename);
1209 clingArgsStorage.push_back(
"-Wno-undefined-inline");
1210 clingArgsStorage.push_back(
"-fsigned-char");
1214 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(
"EXTRA_CLING_ARGS");
1215 if (EnvOpt.hasValue()) {
1216 StringRef Env(*EnvOpt);
1217 while (!Env.empty()) {
1219 std::tie(Arg, Env) = Env.split(
' ');
1220 clingArgsStorage.push_back(Arg.str());
1224 auto GetEnvVarPath = [](
const std::string &EnvVar,
1225 std::vector<std::string> &Paths) {
1226 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1227 if (EnvOpt.hasValue()) {
1228 StringRef Env(*EnvOpt);
1229 while (!Env.empty()) {
1231 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1232 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1233 Paths.push_back(Arg.str());
1238 if (fCxxModulesEnabled) {
1239 std::vector<std::string> Paths;
1243 Paths.push_back(TROOT::GetLibDir().Data());
1244 GetEnvVarPath(
"CLING_PREBUILT_MODULE_PATH", Paths);
1246 std::string EnvVarPath;
1247 for (
const std::string& P : Paths)
1248 EnvVarPath += P + ROOT::FoundationUtils::GetEnvPathSeparator();
1250 gSystem->Setenv(
"CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1254 EnvOpt = llvm::sys::Process::GetEnv(
"ROOT_CLING_TIMING");
1255 if (EnvOpt.hasValue())
1256 clingArgsStorage.push_back(
"-ftime-report");
1261 if (fCxxModulesEnabled && !fromRootCling) {
1263 std::vector<std::string> Paths;
1264 Paths.push_back(TROOT::GetIncludeDir().Data());
1265 GetEnvVarPath(
"CLING_MODULEMAP_PATH", Paths);
1268 Paths.push_back(gSystem->WorkingDirectory());
1270 for (
const std::string& P : Paths) {
1271 std::string ModuleMapLoc = P + ROOT::FoundationUtils::GetPathSeparator()
1272 +
"module.modulemap";
1273 if (!llvm::sys::fs::exists(ModuleMapLoc)) {
1275 ::Info(
"TCling::TCling",
"Modulemap %s does not exist \n",
1276 ModuleMapLoc.c_str());
1281 clingArgsStorage.push_back(
"-fmodule-map-file=" + ModuleMapLoc);
1285 std::vector<const char*> interpArgs;
1286 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1287 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1288 interpArgs.push_back(iArg->c_str());
1294 if (fCxxModulesEnabled) {
1295 if (!fromRootCling) {
1297 interpArgs.push_back(
"-fmodules");
1298 interpArgs.push_back(
"-fno-implicit-module-maps");
1302 interpArgs.push_back(
"-Rmodule-build");
1308 interpArgs.push_back(
"-fno-autolink");
1313 interpArgs.push_back(
"-ffast-math");
1316 TString llvmResourceDir = TROOT::GetEtcDir() +
"/cling";
1318 for (
const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1319 extraArgs && *extraArgs; ++extraArgs) {
1320 if (!strcmp(*extraArgs,
"-resource-dir")) {
1322 llvmResourceDir = *(++extraArgs);
1324 interpArgs.push_back(*extraArgs);
1328 for (
const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1329 interpArgs.push_back(arg.c_str());
1333 cling::Interpreter::ModuleFileExtensions extensions;
1334 EnvOpt = llvm::sys::Process::GetEnv(
"ROOTDEBUG_RDICT");
1335 if (!EnvOpt.hasValue())
1336 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1338 fInterpreter = llvm::make_unique<cling::Interpreter>(interpArgs.size(),
1340 llvmResourceDir, extensions);
1342 if (!fromRootCling) {
1343 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1347 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation =
true;
1351 fInterpreter->getCI()->getLangOpts().SpellChecking =
false;
1356 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO,
false);
1357 fMetaProcessor = llvm::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1359 RegisterCxxModules(*fInterpreter);
1360 RegisterPreIncludedHeaders(*fInterpreter);
1363 fNormalizedCtxt =
new ROOT::TMetaUtils::TNormalizedCtxt(fInterpreter->getLookupHelper());
1364 fLookupHelper =
new ROOT::TMetaUtils::TClingLookupHelper(*fInterpreter, *fNormalizedCtxt,
1365 TClingLookupHelper__ExistingTypeCheck,
1366 TClingLookupHelper__AutoParse,
1368 TClassEdit::Init(fLookupHelper);
1371 fIsAutoParsingSuspended = fromRootCling;
1376 if (!fromRootCling) {
1377 fInterpreter->enableDynamicLookup();
1381 fInterpreter->allowRedefinition();
1386 std::unique_ptr<TClingCallbacks>
1387 clingCallbacks(
new TClingCallbacks(GetInterpreterImpl(), !fromRootCling));
1388 fClingCallbacks = clingCallbacks.get();
1389 fClingCallbacks->SetAutoParsingSuspended(fIsAutoParsingSuspended);
1390 fInterpreter->setCallbacks(std::move(clingCallbacks));
1392 if (!fromRootCling) {
1395 fInterpreter->getDynamicLibraryManager()->addSearchPath(TROOT::GetLibDir().Data());
1407 if (!IsFromRootCling())
1408 GetInterpreterImpl()->runAtExitFuncs();
1409 fIsShuttingDown =
true;
1411 delete fRootmapFiles;
1412 delete fTemporaries;
1413 delete fNormalizedCtxt;
1414 delete fLookupHelper;
1421 void TCling::Initialize()
1423 fClingCallbacks->Initialize();
1426 EnableAutoLoading();
1429 void TCling::ShutDown()
1431 fIsShuttingDown =
true;
1438 static std::string FindLibraryName(
void (*func)())
1440 #if defined(__CYGWIN__) && defined(__GNUC__)
1442 #elif defined(G__WIN32)
1443 MEMORY_BASIC_INFORMATION mbi;
1444 if (!VirtualQuery (func, &mbi,
sizeof (mbi)))
1449 HMODULE hMod = (HMODULE) mbi.AllocationBase;
1450 char moduleName[MAX_PATH];
1452 if (!GetModuleFileNameA (hMod, moduleName,
sizeof (moduleName)))
1456 return ROOT::TMetaUtils::GetRealPath(moduleName);
1459 if (dladdr((
void*)func, &info) == 0) {
1463 if (strchr(info.dli_fname,
'/'))
1464 return ROOT::TMetaUtils::GetRealPath(info.dli_fname);
1468 # if defined(R__MACOSX)
1469 char buf[PATH_MAX] = { 0 };
1470 uint32_t bufsize =
sizeof(buf);
1471 if (_NSGetExecutablePath(buf, &bufsize) >= 0)
1472 return ROOT::TMetaUtils::GetRealPath(buf);
1473 return ROOT::TMetaUtils::GetRealPath(info.dli_fname);
1474 # elif defined(R__UNIX)
1475 char buf[PATH_MAX] = { 0 };
1477 if (readlink(
"/proc/self/exe", buf,
sizeof(buf)) > 0)
1478 return ROOT::TMetaUtils::GetRealPath(buf);
1479 std::string pipeCmd = std::string(
"which \"") + info.dli_fname +
"\"";
1480 FILE* pipe = popen(pipeCmd.c_str(),
"r");
1482 return ROOT::TMetaUtils::GetRealPath(info.dli_fname);
1484 while (fgets(buf,
sizeof(buf), pipe)) {
1488 return ROOT::TMetaUtils::GetRealPath(result);
1490 # error "Unsupported platform."
1501 static bool R__InitStreamerInfoFactory()
1504 auto setFactory = []() {
1505 TVirtualStreamerInfo::SetFactory(
new TStreamerInfo());
1508 static bool doneFactory = setFactory();
1515 void TCling::RegisterRdictForLoadPCM(
const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1517 if (IsFromRootCling())
1520 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1521 ::Error(
"TCling::RegisterRdictForLoadPCM",
"Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1527 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1533 void TCling::LoadPCMImpl(TFile &pcmFile)
1535 auto listOfKeys = pcmFile.GetListOfKeys();
1538 if (listOfKeys && ((listOfKeys->GetSize() == 0) ||
1539 ((listOfKeys->GetSize() == 1) &&
1540 !strcmp(((TKey *)listOfKeys->At(0))->GetName(),
"EMPTY")
1545 TObjArray *protoClasses;
1547 ::Info(
"TCling::LoadPCMImpl",
"reading protoclasses for %s \n", pcmFile.GetName());
1549 pcmFile.GetObject(
"__ProtoClasses", protoClasses);
1552 for (
auto obj : *protoClasses) {
1553 TProtoClass *proto = (TProtoClass *)obj;
1554 TClassTable::Add(proto);
1562 for (
auto proto : *protoClasses) {
1563 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1567 if (existingCl->GetState() != TClass::kHasTClassInit) {
1568 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1570 ::Error(
"TCling::LoadPCM",
"Inconsistent TClassTable for %s", proto->GetName());
1573 TClass *ncl = (*dict)();
1575 ncl->PostLoadCheck();
1581 protoClasses->Clear();
1582 delete protoClasses;
1585 TObjArray *dataTypes;
1586 pcmFile.GetObject(
"__Typedefs", dataTypes);
1588 for (
auto typedf : *dataTypes)
1589 gROOT->GetListOfTypes()->Add(typedf);
1595 pcmFile.GetObject(
"__Enums", enums);
1598 auto listOfGlobals = gROOT->GetListOfGlobals();
1599 auto listOfEnums =
dynamic_cast<THashList *
>(gROOT->GetListOfEnums());
1601 for (
auto selEnum : *enums) {
1602 const char *enumScope = selEnum->GetTitle();
1603 const char *enumName = selEnum->GetName();
1604 if (strcmp(enumScope,
"") == 0) {
1607 if (!listOfEnums->THashList::FindObject(enumName)) {
1608 ((TEnum *)selEnum)->SetClass(
nullptr);
1609 listOfEnums->Add(selEnum);
1611 for (
auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1612 if (!listOfGlobals->FindObject(enumConstant)) {
1613 listOfGlobals->Add(enumConstant);
1619 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1620 if (!nsTClassEntry) {
1621 nsTClassEntry =
new TClass(enumScope, 0, TClass::kNamespaceForMeta,
true);
1623 auto listOfEnums = nsTClassEntry->fEnums.load();
1625 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1628 listOfEnums = nsTClassEntry->fEnums =
new TListOfEnums(nsTClassEntry);
1631 listOfEnums = nsTClassEntry->fEnums =
new TListOfEnumsWithLock(nsTClassEntry);
1634 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1635 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1636 listOfEnums->Add(selEnum);
1648 void TCling::LoadPCM(std::string pcmFileNameFullPath)
1650 SuspendAutoloadingRAII autoloadOff(
this);
1651 SuspendAutoParsing autoparseOff(
this);
1652 assert(!pcmFileNameFullPath.empty());
1653 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1656 TString pcmFileName = pcmFileNameFullPath;
1661 R__InitStreamerInfoFactory();
1663 TDirectory::TContext ctxt;
1664 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1667 ::Info(
"TCling::LoadPCM",
"Loading ROOT PCM %s", pcmFileName.Data());
1672 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1673 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1675 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1676 if (pendingRdict != fPendingRdicts.end()) {
1677 llvm::StringRef pcmContent = pendingRdict->second;
1678 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1679 std::string RDictFileOpts = pcmFileNameFullPath +
"?filetype=pcm";
1680 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1682 LoadPCMImpl(pcmMemFile);
1684 fPendingRdicts.erase(pendingRdict);
1689 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1690 ::Error(
"TCling::LoadPCM",
"ROOT PCM %s file does not exist",
1691 pcmFileNameFullPath.data());
1692 if (!fPendingRdicts.empty())
1693 for (
const auto &rdict : fPendingRdicts)
1694 ::Info(
"TCling::LoadPCM",
"In-memory ROOT PCM candidate %s\n",
1695 rdict.first.c_str());
1699 if (!gROOT->IsRootFile(pcmFileName)) {
1700 Fatal(
"LoadPCM",
"The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1703 TFile pcmFile(pcmFileName +
"?filetype=pcm",
"READ");
1704 LoadPCMImpl(pcmFile);
1710 using namespace clang;
1712 class ExtLexicalStorageAdder:
public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1717 bool VisitRecordDecl(clang::RecordDecl* rcd){
1719 Info(
"ExtLexicalStorageAdder",
1720 "Adding external lexical storage to class %s",
1721 rcd->getNameAsString().c_str());
1722 auto reDeclPtr = rcd->getMostRecentDecl();
1724 reDeclPtr->setHasExternalLexicalStorage();
1725 }
while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1737 bool TCling::RegisterPrebuiltModulePath(
const std::string &FullPath,
1738 const std::string &ModuleMapName )
const
1740 assert(llvm::sys::path::is_absolute(FullPath));
1741 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1742 FileManager &FM = PP.getFileManager();
1745 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1747 HeaderSearch &HS = PP.getHeaderSearchInfo();
1748 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1749 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1750 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1752 HSOpts.AddPrebuiltModulePath(FullPath);
1757 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1758 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1759 const FileEntry *FE = FM.getFile(ModuleMapFileName,
false,
1764 if (FE && !this->IsLoaded(FE->getName().data())) {
1765 if (!HS.loadModuleMapFile(FE,
false))
1767 Error(
"RegisterPrebuiltModulePath",
"Could not load modulemap in %s", ModuleMapFileName.c_str());
1775 static const std::unordered_set<std::string> gIgnoredPCMNames = {
"libCore",
1783 "libforward_listDict",
1791 "libunordered_setDict",
1792 "libunordered_multisetDict",
1793 "libunordered_mapDict",
1794 "libunordered_multimapDict",
1799 static void PrintDlError(
const char *dyLibName,
const char *modulename)
1802 char dyLibError[1000];
1803 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1804 dyLibError,
sizeof(dyLibError), NULL);
1806 const char *dyLibError = dlerror();
1808 ::Error(
"TCling::RegisterModule",
"Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1809 (dyLibError) ? dyLibError :
"");
1815 void TCling::ProcessClassesToUpdate()
1817 while (!fClassesToUpdate.empty()) {
1818 TClass *oldcl = fClassesToUpdate.back().first;
1822 if (oldcl->GetState() != TClass::kHasTClassInit) {
1824 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1825 fClassesToUpdate.pop_back();
1828 TClass *ncl = dict();
1829 if (ncl) ncl->PostLoadCheck();
1831 fClassesToUpdate.pop_back();
1845 void TCling::RegisterModule(
const char* modulename,
1846 const char** headers,
1847 const char** includePaths,
1848 const char* payloadCode,
1849 const char* fwdDeclsCode,
1850 void (*triggerFunc)(),
1851 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
1852 const char** classesHeaders,
1853 Bool_t lateRegistration ,
1854 Bool_t hasCxxModule )
1856 const bool fromRootCling = IsFromRootCling();
1860 if (fromRootCling)
return;
1864 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
1865 fHeaderParsingOnDemand = !hasCxxModule;
1868 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
1869 bool isACLiC = strstr(modulename,
"_ACLiC_dict") !=
nullptr;
1870 if (hasHeaderParsingOnDemand && isACLiC) {
1872 Info(
"TCling::RegisterModule",
1873 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
1874 hasHeaderParsingOnDemand =
false;
1882 fLookedUpClasses.clear();
1886 SuspendAutoloadingRAII autoLoadOff(
this);
1888 for (
const char** inclPath = includePaths; *inclPath; ++inclPath) {
1889 TCling::AddIncludePath(*inclPath);
1891 cling::Transaction* T = 0;
1893 for (
auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
1894 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
1895 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
1896 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
1897 assert(cling::Interpreter::kSuccess == compRes &&
1898 "A fwd declaration could not be compiled");
1899 if (compRes!=cling::Interpreter::kSuccess){
1900 Warning(
"TCling::RegisterModule",
1901 "Problems in declaring string '%s' were encountered.",
1907 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
1908 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
1916 TString code = gNonInterpreterClassDef;
1918 code += payloadCode;
1920 std::string dyLibName = FindLibraryName(triggerFunc);
1921 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
1923 if (dyLibName.empty()) {
1924 ::Error(
"TCling::RegisterModule",
"Dictionary trigger function for %s not found", modulename);
1929 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
1931 bool wasDlopened =
false;
1936 if (!lateRegistration) {
1943 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
1945 fRegisterModuleDyLibs.push_back(dyLibHandle);
1948 PrintDlError(dyLibName.c_str(), modulename);
1953 if (hasHeaderParsingOnDemand && fwdDeclsCode){
1956 std::string fwdDeclsCodeLessEnums;
1960 std::string fwdDeclsLine;
1961 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
1962 std::vector<std::string> scopes;
1963 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
1964 const auto enumPos = fwdDeclsLine.find(
"enum __attribute__((annotate(\"");
1966 if (enumPos != std::string::npos) {
1973 auto nsPos = fwdDeclsLine.find(
"namespace");
1974 R__ASSERT(nsPos < enumPos &&
"Inconsistent enum and enclosing scope parsing!");
1975 while (nsPos < enumPos && nsPos != std::string::npos) {
1977 const auto nsNameStart = nsPos + 10;
1978 const auto nsNameEnd = fwdDeclsLine.find(
'{', nsNameStart);
1979 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
1980 scopes.push_back(nsName);
1981 nsPos = fwdDeclsLine.find(
"namespace", nsNameEnd);
1984 clang::DeclContext* DC = 0;
1985 for (
auto &&aScope: scopes) {
1986 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
1992 if (scopes.empty() || DC) {
1994 size_t posEnumName = fwdDeclsLine.find(
"\"))) ", 32);
1995 R__ASSERT(posEnumName != std::string::npos &&
"Inconsistent enum fwd decl!");
1997 while (isspace(fwdDeclsLine[posEnumName]))
1999 size_t posEnumNameEnd = fwdDeclsLine.find(
" : ", posEnumName);
2000 R__ASSERT(posEnumNameEnd != std::string::npos &&
"Inconsistent enum fwd decl (end)!");
2001 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2005 std::string enumName = fwdDeclsLine.substr(posEnumName,
2006 posEnumNameEnd - posEnumName + 1);
2008 if (clang::NamedDecl* enumDecl
2009 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2010 enumName.c_str(), DC)) {
2013 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) &&
"not an enum decl!");
2020 fwdDeclsCodeLessEnums += fwdDeclsLine +
"\n";
2024 if (fwdDeclsCodeLessEnums.size() != 0){
2025 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2026 assert(cling::Interpreter::kSuccess == compRes &&
2027 "The forward declarations could not be compiled");
2028 if (compRes!=cling::Interpreter::kSuccess){
2029 Warning(
"TCling::RegisterModule",
2030 "Problems in compiling forward declarations for module %s: '%s'",
2031 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2039 ExtLexicalStorageAdder elsa;
2040 for (
auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2041 cling::Transaction::DelayCallInfo& dci = *dciIt;
2042 for(
auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2043 clang::Decl* declPtr = *dit;
2044 elsa.TraverseDecl(declPtr);
2058 for (
const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2059 temp=*classesHeader;
2061 size_t theTemplateHash = 0;
2062 bool addTemplate =
false;
2063 size_t posTemplate = temp.find(
'<');
2064 if (posTemplate != std::string::npos) {
2066 std::string templateName = temp.substr(0, posTemplate);
2067 theTemplateHash = fStringHashFunction(templateName);
2070 size_t theHash = fStringHashFunction(temp);
2072 for (
const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,
"@"); ++classesHeader_inner,++classesHeader){
2074 if (payloadCode == *classesHeader_inner ){
2075 fPayloads.insert(theHash);
2076 if (addTemplate) fPayloads.insert(theTemplateHash);
2079 Info(
"TCling::RegisterModule",
2080 "Adding a header for %s", temp.c_str());
2081 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2083 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2084 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2086 addTemplate =
false;
2092 clang::Sema &TheSema = fInterpreter->getSema();
2094 bool ModuleWasSuccessfullyLoaded =
false;
2096 std::string ModuleName = modulename;
2097 if (llvm::StringRef(modulename).startswith(
"lib"))
2098 ModuleName = llvm::StringRef(modulename).substr(3).str();
2103 clang::Preprocessor &PP = TheSema.getPreprocessor();
2104 std::string ModuleMapName;
2106 ModuleMapName = ModuleName +
".modulemap";
2108 ModuleMapName =
"module.modulemap";
2109 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName),
2114 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2115 if (!ModuleWasSuccessfullyLoaded) {
2117 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2118 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2119 if (moduleMap.findModule(ModuleName))
2120 Info(
"TCling::RegisterModule",
"Module %s in modulemap failed to load.", ModuleName.c_str());
2124 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2125 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2128 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2129 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2130 llvm::sys::path::append(pcmFileNameFullPath,
2131 ROOT::TMetaUtils::GetModuleFileName(modulename));
2132 LoadPCM(pcmFileNameFullPath.str().str());
2139 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2141 #if defined(R__MUST_REVISIT)
2142 #if R__MUST_REVISIT(6,2)
2143 Warning(
"TCling::RegisterModule",
"Diagnostics suppression should be gone by now.");
2147 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2148 SuspendAutoParsing autoParseRaii(
this);
2150 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2151 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2154 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2157 assert(cling::Interpreter::kSuccess == compRes &&
2158 "Payload code of a dictionary could not be parsed correctly.");
2159 if (compRes!=cling::Interpreter::kSuccess) {
2160 Warning(
"TCling::RegisterModule",
2161 "Problems declaring payload for module %s.", modulename) ;
2172 ProcessClassesToUpdate();
2174 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2176 fInterpreter->declare(
"#ifdef __ROOTCLING__\n"
2177 "#undef __ROOTCLING__\n"
2178 + gInterpreterClassDef +
2183 assert(isSharedLib);
2184 void* dyLibHandle = fRegisterModuleDyLibs.back();
2185 fRegisterModuleDyLibs.pop_back();
2186 dlclose(dyLibHandle);
2195 void TCling::RegisterTClassUpdate(TClass *oldcl,DictFuncPtr_t dict)
2197 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2204 void TCling::UnRegisterTClassUpdate(
const TClass *oldcl)
2206 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2207 iterator stop = fClassesToUpdate.end();
2208 for(iterator i = fClassesToUpdate.begin();
2212 if ( i->first == oldcl ) {
2213 fClassesToUpdate.erase(i);
2234 static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2235 const char* input_line,
2236 cling::Interpreter::CompilationResult& compRes,
2237 cling::Value* result)
2240 return metaProcessor->process(input_line, compRes, result);
2242 catch (cling::InterpreterException& ex)
2244 Error(
"HandleInterpreterException",
"%s.\n%s", ex.what(),
"Execution of your code was aborted.");
2246 compRes = cling::Interpreter::kFailure;
2253 bool TCling::DiagnoseIfInterpreterException(
const std::exception &e)
const
2255 if (
auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2264 Long_t TCling::ProcessLine(
const char* line, EErrorCode* error)
2271 TString sLine(line);
2272 if (strstr(line,fantomline)) {
2279 if (gApplication->IsCmdThread()) {
2280 R__LOCKGUARD(fLockProcessLine ? gInterpreterMutex : 0);
2281 gROOT->SetLineIsProcessing();
2283 UpdateAllCanvases();
2285 gROOT->SetLineHasBeenProcessed();
2291 if (gGlobalMutex && !gInterpreterMutex && fLockProcessLine) {
2292 gGlobalMutex->Lock();
2293 if (!gInterpreterMutex)
2294 gInterpreterMutex = gGlobalMutex->Factory(kTRUE);
2295 gGlobalMutex->UnLock();
2297 R__LOCKGUARD_CLING(fLockProcessLine ? gInterpreterMutex : 0);
2298 gROOT->SetLineIsProcessing();
2300 struct InterpreterFlagsRAII {
2301 cling::Interpreter* fInterpreter;
2302 bool fWasDynamicLookupEnabled;
2304 InterpreterFlagsRAII(cling::Interpreter* interp):
2305 fInterpreter(interp),
2306 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2308 fInterpreter->enableDynamicLookup(
true);
2310 ~InterpreterFlagsRAII() {
2311 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2312 gROOT->SetLineHasBeenProcessed();
2314 } interpreterFlagsRAII(GetInterpreterImpl());
2320 cling::Value result;
2321 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2322 if (!strncmp(sLine.Data(),
".L", 2) || !strncmp(sLine.Data(),
".x", 2) ||
2323 !strncmp(sLine.Data(),
".X", 2)) {
2326 TString mod_line(sLine);
2330 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2331 aclicMode, arguments, io);
2332 if (aclicMode.Length()) {
2334 R__ASSERT(aclicMode[0]==
'+' &&
"ACLiC mode must start with a +");
2336 if (aclicMode[1]==
'+') {
2340 if (!gSystem->CompileMacro(fname,aclicMode)) {
2342 compRes = cling::Interpreter::kFailure;
2344 if (strncmp(sLine.Data(),
".L", 2) != 0) {
2347 if (arguments.Length()==0) {
2351 Ssiz_t ext = fname.Last(
'.');
2355 const char *
function = gSystem->BaseName(fname);
2356 mod_line =
function + arguments + io;
2357 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2362 size_t unnamedMacroOpenCurly;
2365 std::string codeline;
2366 std::ifstream in(fname);
2368 std::getline(in, codeline);
2369 code += codeline +
"\n";
2371 unnamedMacroOpenCurly
2372 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2375 fCurExecutingMacros.push_back(fname);
2376 if (unnamedMacroOpenCurly != std::string::npos) {
2377 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2378 unnamedMacroOpenCurly);
2381 fInterpreter->enableDynamicLookup(
false);
2382 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2384 fCurExecutingMacros.pop_back();
2388 if (0!=strncmp(sLine.Data(),
".autodict ",10) && sLine !=
".autodict") {
2393 bool isInclusionDirective = sLine.Contains(
"\n#include") || sLine.BeginsWith(
"#include");
2394 if (isInclusionDirective) {
2395 SuspendAutoParsing autoParseRaii(
this);
2396 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2398 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2402 if (result.isValid())
2403 RegisterTemporary(result);
2406 *error = kProcessing;
2411 case cling::Interpreter::kSuccess: *error = kNoError;
break;
2412 case cling::Interpreter::kFailure: *error = kRecoverable;
break;
2413 case cling::Interpreter::kMoreInputExpected: *error = kProcessing;
break;
2416 if (compRes == cling::Interpreter::kSuccess
2418 && !result.isVoid())
2420 return result.simplisticCastAs<
long>();
2428 void TCling::PrintIntro()
2437 void TCling::AddIncludePath(
const char *path)
2439 R__LOCKGUARD(gInterpreterMutex);
2442 if (path[0] ==
'-' && path[1] ==
'I')
2445 fInterpreter->AddIncludePath(path);
2451 void TCling::InspectMembers(TMemberInspector& insp,
const void* obj,
2452 const TClass* cl, Bool_t isTransient)
2454 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2455 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
2456 : TMemberInspector::kNoObjectGiven);
2459 if (!cl || cl->GetCollectionProxy()) {
2466 static const TClassRef clRefString(
"std::string");
2467 if (clRefString == cl) {
2472 if (TClassEdit::IsStdArray(cl->GetName())) {
2477 const char* cobj = (
const char*) obj;
2484 auto inspInspect = [&] (ptrdiff_t offset){
2485 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(),
"_real", cobj, isTransient);
2486 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(),
"_imag", cobj + offset, isTransient);
2489 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2490 switch(complexType) {
2491 case TClassEdit::EComplexType::kNone:
2495 case TClassEdit::EComplexType::kFloat:
2497 inspInspect(
sizeof(
float));
2500 case TClassEdit::EComplexType::kDouble:
2502 inspInspect(
sizeof(
double));
2505 case TClassEdit::EComplexType::kInt:
2507 inspInspect(
sizeof(
int));
2510 case TClassEdit::EComplexType::kLong:
2512 inspInspect(
sizeof(
long));
2517 static clang::PrintingPolicy
2518 printPol(fInterpreter->getCI()->getLangOpts());
2519 if (printPol.Indentation) {
2521 printPol.Indentation = 0;
2522 printPol.SuppressInitializers =
true;
2525 const char* clname = cl->GetName();
2528 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2529 const clang::Decl *scopeDecl = 0;
2530 const clang::Type *recordType = 0;
2532 if (cl->GetClassInfo()) {
2533 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2534 scopeDecl = clingCI->GetDecl();
2535 recordType = clingCI->GetType();
2537 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2539 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2543 Error(
"InspectMembers",
"Cannot find Decl for class %s", clname);
2546 const clang::CXXRecordDecl* recordDecl
2547 = llvm::dyn_cast<
const clang::CXXRecordDecl>(scopeDecl);
2549 Error(
"InspectMembers",
"Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2556 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2558 astContext.getASTRecordLayout(recordDecl);
2560 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2561 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2564 const clang::ASTRecordLayout& recLayout
2565 = astContext.getASTRecordLayout(recordDecl);
2572 if (cl->Size() != recLayout.getSize().getQuantity()) {
2573 Error(
"InspectMembers",
"TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2574 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2577 unsigned iNField = 0;
2580 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2581 eField = recordDecl->field_end(); iField != eField;
2582 ++iField, ++iNField) {
2585 clang::QualType memberQT = iField->getType();
2588 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2590 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(),
false );
2591 if (memberQT.isNull()) {
2592 std::string memberName;
2593 llvm::raw_string_ostream stream(memberName);
2595 printPol.AnonymousTagLocations =
false;
2596 iField->getNameForDiagnostic(stream, printPol,
true );
2598 Error(
"InspectMembers",
2599 "Cannot retrieve QualType for member %s while inspecting class %s",
2600 memberName.c_str(), clname);
2603 const clang::Type* memType = memberQT.getTypePtr();
2605 std::string memberName;
2606 llvm::raw_string_ostream stream(memberName);
2608 printPol.AnonymousTagLocations =
false;
2609 iField->getNameForDiagnostic(stream, printPol,
true );
2611 Error(
"InspectMembers",
2612 "Cannot retrieve Type for member %s while inspecting class %s",
2613 memberName.c_str(), clname);
2617 const clang::Type* memNonPtrType = memType;
2618 Bool_t ispointer =
false;
2619 if (memNonPtrType->isPointerType()) {
2621 clang::QualType ptrQT
2622 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2625 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2627 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(),
false );
2628 if (ptrQT.isNull()) {
2629 std::string memberName;
2630 llvm::raw_string_ostream stream(memberName);
2632 printPol.AnonymousTagLocations =
false;
2633 iField->getNameForDiagnostic(stream, printPol,
true );
2635 Error(
"InspectMembers",
2636 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2637 memberName.c_str(), clname);
2640 memNonPtrType = ptrQT.getTypePtr();
2644 llvm::SmallString<8> arraySize;
2645 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2646 unsigned arrLevel = 0;
2647 bool haveErrorDueToArray =
false;
2651 const clang::ConstantArrayType* constArrType =
2652 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2654 constArrType->getSize().toStringUnsigned(arraySize);
2657 clang::QualType subArrQT = arrType->getElementType();
2658 if (subArrQT.isNull()) {
2659 std::string memberName;
2660 llvm::raw_string_ostream stream(memberName);
2662 printPol.AnonymousTagLocations =
false;
2663 iField->getNameForDiagnostic(stream, printPol,
true );
2665 Error(
"InspectMembers",
2666 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2667 arrLevel, subArrQT.getAsString(printPol).c_str(),
2668 memberName.c_str(), clname);
2669 haveErrorDueToArray =
true;
2672 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2674 if (haveErrorDueToArray) {
2679 std::string fieldName;
2680 if (memType->isPointerType()) {
2685 std::string ioname(iField->getName());
2686 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,
"ioname",ioname);
2687 fieldName += ioname;
2688 fieldName += arraySize;
2693 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2694 ptrdiff_t fieldOffset = offset.getQuantity();
2703 if (!insp.IsTreatingNonAccessibleTypes()){
2704 auto iFiledQtype = iField->getType();
2705 if (
auto tagDecl = iFiledQtype->getAsTagDecl()){
2706 auto declAccess = tagDecl->getAccess();
2707 if (declAccess == AS_private || declAccess == AS_protected) {
2713 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2716 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2717 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2720 std::string sFieldRecName;
2721 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,
"iotype",sFieldRecName)){
2722 ROOT::TMetaUtils::GetNormalizedName(sFieldRecName,
2723 clang::QualType(memNonPtrType,0),
2728 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2731 Bool_t
transient = isTransient || !mbr || !mbr->IsPersistent();
2733 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2734 (fieldName +
'.').c_str(),
transient);
2742 unsigned iNBase = 0;
2743 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2744 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2745 iBase != eBase; ++iBase, ++iNBase) {
2746 clang::QualType baseQT = iBase->getType();
2747 if (baseQT.isNull()) {
2748 Error(
"InspectMembers",
2749 "Cannot find QualType for base number %d while inspecting class %s",
2753 const clang::CXXRecordDecl* baseDecl
2754 = baseQT->getAsCXXRecordDecl();
2756 Error(
"InspectMembers",
2757 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2761 TClass* baseCl=
nullptr;
2762 std::string sBaseName;
2764 std::vector<TClass*> foundClasses;
2765 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2766 if (foundClasses.size()==1){
2767 baseCl=foundClasses[0];
2771 ROOT::TMetaUtils::GetNormalizedName(sBaseName,
2775 baseCl = TClass::GetClass(sBaseName.c_str());
2780 std::string qualNameForDiag;
2781 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2782 Error(
"InspectMembers",
2783 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2788 if (iBase->isVirtual()) {
2789 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
2791 Error(
"InspectMembers",
2792 "Base %s of class %s is virtual but no object provided",
2793 sBaseName.c_str(), clname);
2795 baseOffset = TVirtualStreamerInfo::kNeedObjectForVirtualBaseClass;
2798 TClingClassInfo* ci = (TClingClassInfo*)cl->GetClassInfo();
2799 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
2801 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
2803 if (baseOffset == -1) {
2804 Error(
"InspectMembers",
2805 "Error calculating offset of virtual base %s of class %s",
2806 sBaseName.c_str(), clname);
2809 Error(
"InspectMembers",
2810 "Cannot calculate offset of virtual base %s of class %s",
2811 sBaseName.c_str(), clname);
2816 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
2819 if (baseCl->IsLoaded()) {
2823 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
2825 baseCl->CallShowMembers(cobj + baseOffset,
2835 void TCling::ClearFileBusy()
2843 void TCling::ClearStack()
2856 bool TCling::Declare(
const char* code)
2858 R__LOCKGUARD_CLING(gInterpreterMutex);
2860 SuspendAutoloadingRAII autoLoadOff(
this);
2861 SuspendAutoParsing autoParseRaii(
this);
2863 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
2864 fInterpreter->enableDynamicLookup(
false);
2865 bool oldRawInput = fInterpreter->isRawInputEnabled();
2866 fInterpreter->enableRawInput(
true);
2868 Bool_t ret = LoadText(code);
2870 fInterpreter->enableRawInput(oldRawInput);
2871 fInterpreter->enableDynamicLookup(oldDynLookup);
2881 void TCling::EnableAutoLoading()
2883 if (IsFromRootCling())
2890 assert(GetRootMapFiles() == 0 &&
"Must be called before LoadLibraryMap!");
2891 TClass::ReadRules();
2894 SetClassAutoloading(
true);
2901 void TCling::EndOfLineAction()
2903 ProcessLineSynch(fantomline);
2909 static Bool_t s_IsLibraryLoaded(
const char* libname, cling::Interpreter* fInterpreter)
2912 TString tLibName(libname);
2913 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
2914 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
2918 Bool_t TCling::IsLibraryLoaded(
const char* libname)
const
2920 R__LOCKGUARD(gInterpreterMutex);
2921 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
2927 Bool_t TCling::HasPCMForLibrary(
const char *libname)
const
2929 llvm::StringRef ModuleName(libname);
2930 ModuleName = llvm::sys::path::stem(ModuleName);
2931 ModuleName.consume_front(
"lib");
2933 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
2934 clang::Module *M = moduleMap.findModule(ModuleName);
2935 return M && !M->IsMissingRequirement && M->getASTFile();
2946 Bool_t TCling::IsLoaded(
const char* filename)
const
2948 R__LOCKGUARD(gInterpreterMutex);
2953 std::string file_name = filename;
2954 size_t at = std::string::npos;
2955 while ((at = file_name.find(
"/./")) != std::string::npos)
2956 file_name.replace(at, 3,
"/");
2958 std::string filesStr =
"";
2959 llvm::raw_string_ostream filesOS(filesStr);
2960 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
2961 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
2964 llvm::SmallVector<llvm::StringRef, 100> files;
2965 llvm::StringRef(filesStr).split(files,
"\n");
2967 std::set<std::string> fileMap;
2969 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
2970 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
2971 if ((*iF) == file_name.c_str())
return kTRUE;
2972 fileMap.insert(*iF);
2975 if (fileMap.empty())
return kFALSE;
2978 TString sFilename(file_name.c_str());
2979 if (gSystem->FindFile(TROOT::GetMacroPath(), sFilename, kReadPermission)
2980 && fileMap.count(sFilename.Data())) {
2985 TString incPath = gSystem->GetIncludePath();
2986 incPath.Append(
":").Prepend(
" ");
2987 incPath.ReplaceAll(
" -I",
":");
2988 while (incPath.Index(
" :") != -1) {
2989 incPath.ReplaceAll(
" :",
":");
2991 incPath.Prepend(
".:");
2992 sFilename = file_name.c_str();
2993 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
2994 && fileMap.count(sFilename.Data())) {
2999 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3003 const clang::DirectoryLookup *CurDir = 0;
3004 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3005 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3006 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
3007 clang::SourceLocation(),
3010 clang::ArrayRef<std::pair<
const clang::FileEntry *,
3011 const clang::DirectoryEntry *>>(),
3021 if (FE && FE->isValid()) {
3023 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3025 clang::FileID FID = SM.translateFile(FE);
3026 if (!FID.isInvalid() && FID.getHashValue() == 0)
3029 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3030 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
3032 if (!FID.isInvalid())
3036 sFilename = FE->getName();
3037 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3038 && fileMap.count(sFilename.Data())) {
3047 void TCling::UpdateListOfLoadedSharedLibraries()
3049 #if defined(R__WIN32) || defined(__CYGWIN__)
3050 HMODULE hModules[1024];
3052 unsigned long cbModules;
3054 hProcess = (
void *)::GetCurrentProcess();
3055 ::EnumProcessModules(hProcess, hModules,
sizeof(hModules), &cbModules);
3057 for (i = 1; i < (cbModules /
sizeof(
void *)); i++) {
3058 static const int bufsize = 260;
3059 wchar_t winname[bufsize];
3060 char posixname[bufsize];
3061 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3062 #if defined(__CYGWIN__)
3063 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3065 std::wstring wpath = winname;
3066 std::replace(wpath.begin(), wpath.end(),
'\\',
'/');
3067 string path(wpath.begin(), wpath.end());
3068 strncpy(posixname, path.c_str(), bufsize);
3070 if (!fSharedLibs.Contains(posixname)) {
3071 RegisterLoadedSharedLibrary(posixname);
3074 #elif defined(R__MACOSX)
3076 uint32_t imageIndex = (uint32_t) (
size_t) fPrevLoadedDynLibInfo;
3078 while (
const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3080 if (mh->filetype == MH_DYLIB) {
3081 if (
const char* imageName = _dyld_get_image_name(imageIndex)) {
3082 RegisterLoadedSharedLibrary(imageName);
3088 fPrevLoadedDynLibInfo = (
void*)(
size_t)imageIndex;
3089 #elif defined(R__LINUX)
3101 if (!fPrevLoadedDynLibInfo || fPrevLoadedDynLibInfo == (
void*)(size_t)-1) {
3102 PointerNo4* procLinkMap = (PointerNo4*)dlopen(0, RTLD_LAZY | RTLD_GLOBAL);
3105 LinkMap* linkMap = (LinkMap*) ((PointerNo4*)procLinkMap->fPtr)->fPtr;
3106 RegisterLoadedSharedLibrary(linkMap->fName);
3107 fPrevLoadedDynLibInfo = linkMap;
3109 dlclose(procLinkMap);
3112 LinkMap* iDyLib = (LinkMap*)fPrevLoadedDynLibInfo;
3113 while (iDyLib->fNext) {
3114 iDyLib = iDyLib->fNext;
3115 RegisterLoadedSharedLibrary(iDyLib->fName);
3117 fPrevLoadedDynLibInfo = iDyLib;
3119 Error(
"TCling::UpdateListOfLoadedSharedLibraries",
3120 "Platform not supported!");
3128 void TCling::RegisterLoadedSharedLibrary(
const char* filename)
3131 if (!filename)
return;
3135 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3136 if (!DLM->isLibraryLoaded(filename)) {
3137 DLM->loadLibrary(filename,
true );
3140 #if defined(R__MACOSX)
3142 auto lenFilename = strlen(filename);
3143 if (!strncmp(filename,
"/usr/lib/system/", 16)
3144 || !strncmp(filename,
"/usr/lib/libc++", 15)
3145 || !strncmp(filename,
"/System/Library/Frameworks/", 27)
3146 || !strncmp(filename,
"/System/Library/PrivateFrameworks/", 34)
3147 || !strncmp(filename,
"/System/Library/CoreServices/", 29)
3148 || !strcmp(filename,
"cl_kernels")
3149 || strstr(filename,
"/usr/lib/libSystem")
3150 || strstr(filename,
"/usr/lib/libstdc++")
3151 || strstr(filename,
"/usr/lib/libicucore")
3152 || strstr(filename,
"/usr/lib/libbsm")
3153 || strstr(filename,
"/usr/lib/libobjc")
3154 || strstr(filename,
"/usr/lib/libresolv")
3155 || strstr(filename,
"/usr/lib/libauto")
3156 || strstr(filename,
"/usr/lib/libcups")
3157 || strstr(filename,
"/usr/lib/libDiagnosticMessagesClient")
3158 || strstr(filename,
"/usr/lib/liblangid")
3159 || strstr(filename,
"/usr/lib/libCRFSuite")
3160 || strstr(filename,
"/usr/lib/libpam")
3161 || strstr(filename,
"/usr/lib/libOpenScriptingUtil")
3162 || strstr(filename,
"/usr/lib/libextension")
3163 || strstr(filename,
"/usr/lib/libAudioToolboxUtility")
3167 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4,
".tbd")))
3169 #elif defined(__CYGWIN__)
3171 static const int bufsize = 260;
3172 char posixwindir[bufsize];
3173 char *windir = getenv(
"WINDIR");
3175 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3177 snprintf(posixwindir,
sizeof(posixwindir),
"/Windows/");
3178 if (strstr(filename, posixwindir) ||
3179 strstr(filename,
"/usr/bin/cyg"))
3181 #elif defined(R__WIN32)
3182 if (strstr(filename,
"/Windows/"))
3184 #elif defined (R__LINUX)
3185 if (strstr(filename,
"/ld-linux")
3186 || strstr(filename,
"linux-gnu/")
3187 || strstr(filename,
"/libstdc++.")
3188 || strstr(filename,
"/libgcc")
3189 || strstr(filename,
"/libc.")
3190 || strstr(filename,
"/libdl.")
3191 || strstr(filename,
"/libm."))
3195 if (!fSharedLibs.IsNull()) {
3196 fSharedLibs.Append(
" ");
3198 fSharedLibs.Append(filename);
3206 Int_t TCling::Load(
const char* filename, Bool_t system)
3208 assert(!IsFromRootCling() &&
"Trying to load library from rootcling!");
3211 R__LOCKGUARD_CLING(gInterpreterMutex);
3212 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3213 std::string canonLib = DLM->lookupLibrary(filename);
3214 cling::DynamicLibraryManager::LoadLibResult res
3215 = cling::DynamicLibraryManager::kLoadLibNotFound;
3216 if (!canonLib.empty()) {
3218 res = DLM->loadLibrary(filename, system);
3222 cling::Interpreter::CompilationResult compRes;
3223 HandleInterpreterException(GetMetaProcessorImpl(), Form(
".L %s", canonLib.c_str()), compRes, 0);
3224 if (compRes == cling::Interpreter::kSuccess)
3225 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3229 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3230 UpdateListOfLoadedSharedLibraries();
3233 case cling::DynamicLibraryManager::kLoadLibSuccess:
return 0;
3234 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded:
return 1;
3243 void TCling::LoadMacro(
const char* filename, EErrorCode* error)
3245 ProcessLine(Form(
".L %s", filename), error);
3251 Long_t TCling::ProcessLineAsynch(
const char* line, EErrorCode* error)
3253 return ProcessLine(line, error);
3260 Long_t TCling::ProcessLineSynch(
const char* line, EErrorCode* error)
3262 R__LOCKGUARD_CLING(fLockProcessLine ? gInterpreterMutex : 0);
3264 if (gApplication->IsCmdThread()) {
3265 return ProcessLine(line, error);
3269 return ProcessLine(line, error);
3276 Long_t TCling::Calc(
const char* line, EErrorCode* error)
3282 if (gApplication && gApplication->GetApplicationImp()) {
3283 while (gROOT->IsLineProcessing() && !gApplication) {
3284 Warning(
"Calc",
"waiting for cling thread to free");
3285 gSystem->Sleep(500);
3287 gROOT->SetLineIsProcessing();
3290 R__LOCKGUARD_CLING(gInterpreterMutex);
3292 *error = TInterpreter::kNoError;
3294 cling::Value valRef;
3295 cling::Interpreter::CompilationResult cr = fInterpreter->evaluate(line, valRef);
3296 if (cr != cling::Interpreter::kSuccess) {
3300 *error = TInterpreter::kRecoverable;
3304 if (!valRef.isValid()) {
3308 *error = TInterpreter::kDangerous;
3313 if (valRef.isVoid()) {
3317 RegisterTemporary(valRef);
3319 if (gApplication && gApplication->GetApplicationImp()) {
3320 gROOT->SetLineHasBeenProcessed();
3323 return valRef.simplisticCastAs<
long>();
3329 void TCling::SetGetline(
const char * (*getlineFunc)(
const char* prompt),
3330 void (*histaddFunc)(
const char* line))
3335 #if defined(R__MUST_REVISIT)
3336 #if R__MUST_REVISIT(6,2)
3337 Warning(
"SetGetline",
"Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3346 Bool_t TCling::HandleNewTransaction(
const cling::Transaction &T)
3348 R__LOCKGUARD(gInterpreterMutex);
3350 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3351 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3352 || T.macros_begin() != T.macros_end()
3353 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3354 fTransactionCount++;
3364 void TCling::RecursiveRemove(TObject* obj)
3372 R__READ_LOCKGUARD(ROOT::gCoreMutex);
3375 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3376 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3377 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3378 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
3380 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3389 void TCling::Reset()
3391 fMetaProcessor->cancelContinuation();
3394 #if defined(R__MUST_REVISIT)
3395 #if R__MUST_REVISIT(6,2)
3396 R__LOCKGUARD(gInterpreterMutex);
3397 Warning(
"Reset",
"Cling should support the equivalent of scratch_upto(&fDictPos)");
3405 void TCling::ResetAll()
3407 #if defined(R__MUST_REVISIT)
3408 #if R__MUST_REVISIT(6,2)
3409 R__LOCKGUARD(gInterpreterMutex);
3410 Warning(
"ResetAll",
"Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3421 void TCling::ResetGlobals()
3423 R__LOCKGUARD(gInterpreterMutex);
3428 fInterpreter->runAndRemoveStaticDestructors();
3435 void TCling::ResetGlobalVar(
void* obj)
3437 #if defined(R__MUST_REVISIT)
3438 #if R__MUST_REVISIT(6,2)
3439 R__LOCKGUARD(gInterpreterMutex);
3440 Warning(
"ResetGlobalVar",
"Cling should support the equivalent of resetglobalvar(obj)");
3450 void TCling::RewindDictionary()
3452 #if defined(R__MUST_REVISIT)
3453 #if R__MUST_REVISIT(6,2)
3454 R__LOCKGUARD(gInterpreterMutex);
3455 Warning(
"RewindDictionary",
"Cling should provide a way to revert transaction similar to rewinddictionary()");
3464 Int_t TCling::DeleteGlobal(
void* obj)
3466 #if defined(R__MUST_REVISIT)
3467 #if R__MUST_REVISIT(6,2)
3468 R__LOCKGUARD(gInterpreterMutex);
3469 Warning(
"DeleteGlobal",
"Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3479 Int_t TCling::DeleteVariable(
const char* name)
3481 #if defined(R__MUST_REVISIT)
3482 #if R__MUST_REVISIT(6,2)
3483 Warning(
"DeleteVariable",
"should do more that just reseting the value to zero");
3487 R__LOCKGUARD(gInterpreterMutex);
3488 llvm::StringRef srName(name);
3489 const char* unscopedName = name;
3490 llvm::StringRef::size_type posScope = srName.rfind(
"::");
3491 const clang::DeclContext* declCtx = 0;
3492 if (posScope != llvm::StringRef::npos) {
3493 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3494 const clang::Decl* scopeDecl
3495 = lh.findScope(srName.substr(0, posScope),
3496 cling::LookupHelper::WithDiagnostics);
3498 Error(
"DeleteVariable",
"Cannot find enclosing scope for variable %s",
3502 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3504 Error(
"DeleteVariable",
3505 "Enclosing scope for variable %s is not a declaration context",
3509 unscopedName += posScope + 2;
3512 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3513 clang::NamedDecl* nVarDecl
3514 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3516 Error(
"DeleteVariable",
"Unknown variable %s", name);
3519 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3521 Error(
"DeleteVariable",
"Entity %s is not a variable", name);
3525 clang::QualType qType = varDecl->getType();
3526 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3529 if (type->isPointerType()) {
3530 int** ppInt = (
int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3532 if (ppInt) *ppInt = 0;
3540 void TCling::SaveContext()
3542 #if defined(R__MUST_REVISIT)
3543 #if R__MUST_REVISIT(6,2)
3544 R__LOCKGUARD(gInterpreterMutex);
3545 Warning(
"SaveContext",
"Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3553 void TCling::SaveGlobalsContext()
3555 #if defined(R__MUST_REVISIT)
3556 #if R__MUST_REVISIT(6,2)
3557 R__LOCKGUARD(gInterpreterMutex);
3558 Warning(
"SaveGlobalsContext",
"Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3566 void TCling::UpdateListOfGlobals()
3573 void TCling::UpdateListOfGlobalFunctions()
3580 void TCling::UpdateListOfTypes()
3586 enum class ETupleOrdering {
3592 struct AlternateTupleIntDoubleAsc
3598 struct AlternateTupleIntDoubleDes
3604 static ETupleOrdering IsTupleAscending()
3606 std::tuple<int,double> value;
3607 AlternateTupleIntDoubleAsc asc;
3608 AlternateTupleIntDoubleDes des;
3610 size_t offset0 = ((
char*)&(std::get<0>(value))) - ((
char*)&value);
3611 size_t offset1 = ((
char*)&(std::get<1>(value))) - ((
char*)&value);
3613 size_t ascOffset0 = ((
char*)&(asc._0)) - ((
char*)&asc);
3614 size_t ascOffset1 = ((
char*)&(asc._1)) - ((
char*)&asc);
3616 size_t desOffset0 = ((
char*)&(des._0)) - ((
char*)&des);
3617 size_t desOffset1 = ((
char*)&(des._1)) - ((
char*)&des);
3619 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3620 return ETupleOrdering::kAscending;
3621 }
else if (offset0 == desOffset0 && offset1 == desOffset1) {
3622 return ETupleOrdering::kDescending;
3624 return ETupleOrdering::kUnexpected;
3628 static std::string AlternateTuple(
const char *classname,
const cling::LookupHelper& lh)
3630 TClassEdit::TSplitType tupleContent(classname);
3631 std::string alternateName =
"TEmulatedTuple";
3632 alternateName.append( classname + 5 );
3634 std::string fullname =
"ROOT::Internal::" + alternateName;
3635 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3639 std::string guard_name;
3640 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3641 std::ostringstream guard;
3642 guard <<
"ROOT_INTERNAL_TEmulated_";
3643 guard << guard_name;
3645 std::ostringstream alternateTuple;
3646 alternateTuple <<
"#ifndef " << guard.str() <<
"\n";
3647 alternateTuple <<
"#define " << guard.str() <<
"\n";
3648 alternateTuple <<
"namespace ROOT { namespace Internal {\n";
3649 alternateTuple <<
"template <class... Types> struct TEmulatedTuple;\n";
3650 alternateTuple <<
"template <> struct " << alternateName <<
" {\n";
3653 switch(IsTupleAscending()) {
3654 case ETupleOrdering::kAscending: {
3655 unsigned int nMember = 0;
3656 auto iter = tupleContent.fElements.begin() + 1;
3657 auto theEnd = tupleContent.fElements.end() - 1;
3658 while (iter != theEnd) {
3659 alternateTuple <<
" " << *iter <<
" _" << nMember <<
";\n";
3665 case ETupleOrdering::kDescending: {
3666 unsigned int nMember = tupleContent.fElements.size() - 3;
3667 auto iter = tupleContent.fElements.rbegin() + 1;
3668 auto theEnd = tupleContent.fElements.rend() - 1;
3669 while (iter != theEnd) {
3670 alternateTuple <<
" " << *iter <<
" _" << nMember <<
";\n";
3676 case ETupleOrdering::kUnexpected: {
3677 Fatal(
"TCling::SetClassInfo::AlternateTuple",
3678 "Layout of std::tuple on this platform is unexpected.");
3683 alternateTuple <<
"};\n";
3684 alternateTuple <<
"}}\n";
3685 alternateTuple <<
"#endif\n";
3686 if (!gCling->Declare(alternateTuple.str().c_str())) {
3687 Error(
"Load",
"Could not declare %s",alternateName.c_str());
3690 alternateName =
"ROOT::Internal::" + alternateName;
3691 return alternateName;
3699 void TCling::SetClassInfo(TClass* cl, Bool_t reload)
3703 if (fIsShuttingDown) {
3705 if (cl->fClassInfo) {
3706 R__LOCKGUARD(gInterpreterMutex);
3707 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3710 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3713 cl->fClassInfo =
nullptr;
3718 R__LOCKGUARD(gInterpreterMutex);
3719 if (cl->fClassInfo && !reload) {
3723 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3725 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3729 std::string name(cl->GetName());
3734 if (strncmp(cl->GetName(),
"tuple<",strlen(
"tuple<"))==0) {
3736 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
3740 TClingClassInfo* info =
new TClingClassInfo(GetInterpreterImpl(), name.c_str());
3741 if (!info->IsValid()) {
3742 if (cl->fState != TClass::kHasTClassInit) {
3743 if (cl->fStreamerInfo->GetEntries() != 0) {
3744 cl->fState = TClass::kEmulated;
3746 cl->fState = TClass::kForwardDeclared;
3752 cl->fClassInfo = (ClassInfo_t*)info;
3760 Bool_t zombieCandidate = kFALSE;
3763 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
3765 zombieCandidate = kTRUE;
3767 if (!info->IsLoaded()) {
3768 if (info->Property() & (kIsNamespace)) {
3772 zombieCandidate = kTRUE;
3778 if (zombieCandidate && !cl->GetCollectionType()) {
3782 if (cl->fState != TClass::kHasTClassInit) {
3783 if (cl->fClassInfo) {
3784 cl->fState = TClass::kInterpreted;
3785 cl->ResetBit(TClass::kIsEmulation);
3791 if (cl->fStreamerInfo->GetEntries() != 0) {
3792 cl->fState = TClass::kEmulated;
3794 cl->fState = TClass::kForwardDeclared;
3799 if (cl->fClassInfo) {
3800 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
3822 TInterpreter::ECheckClassInfo
3823 TCling::CheckClassInfo(
const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly )
3825 R__LOCKGUARD(gInterpreterMutex);
3826 static const char *anonEnum =
"anonymous enum ";
3827 static const int cmplen = strlen(anonEnum);
3829 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
3834 autoload = autoload && IsClassAutoloadingEnabled();
3838 THashTable *typeTable =
dynamic_cast<THashTable*
>( gROOT->GetListOfTypes() );
3839 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
3841 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
3842 && fundType->GetType() > 0) {
3851 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
3854 const char *classname = name;
3856 int storeAutoload = SetClassAutoloading(autoload);
3865 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3866 const clang::Type *type = 0;
3867 const clang::Decl *decl
3868 = lh.findScope(classname,
3869 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3870 : cling::LookupHelper::NoDiagnostics,
3873 std::string buf = TClassEdit::InsertStd(classname);
3874 decl = lh.findScope(buf,
3875 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3876 : cling::LookupHelper::NoDiagnostics,
3893 clang::ClassTemplateSpecializationDecl *tmpltDecl =
3894 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
3895 (type->getAsCXXRecordDecl());
3896 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
3900 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
3902 SetClassAutoloading(storeAutoload);
3907 TClingClassInfo tci(GetInterpreterImpl(), *type);
3908 if (!tci.IsValid()) {
3909 SetClassAutoloading(storeAutoload);
3912 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
3913 kIsClass | kIsStruct | kIsNamespace | kIsEnum | kIsUnion;
3915 if (tci.Property() & propertiesMask) {
3916 bool hasClassDefInline =
false;
3917 if (isClassOrNamespaceOnly) {
3920 auto hasDictionary = tci.GetMethod(
"Dictionary",
"",
false, 0, ROOT::kExactMatch);
3921 auto implLineFunc = tci.GetMethod(
"ImplFileLine",
"",
false, 0, ROOT::kExactMatch);
3923 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
3925 bool success =
false;
3926 std::tie(success, lineNumber) =
3927 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetMethodDecl(), *fInterpreter);
3928 hasClassDefInline = success && (lineNumber == -1);
3936 SetClassAutoloading(storeAutoload);
3937 if (hasClassDefInline)
3938 return kWithClassDefInline;
3943 SetClassAutoloading(storeAutoload);
3948 SetClassAutoloading(storeAutoload);
3978 Bool_t TCling::CheckClassTemplate(
const char *name)
3980 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3981 const clang::Decl *decl
3982 = lh.findClassTemplate(name,
3983 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3984 : cling::LookupHelper::NoDiagnostics);
3986 std::string strname =
"std::";
3988 decl = lh.findClassTemplate(strname,
3989 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
3990 : cling::LookupHelper::NoDiagnostics);
3998 void TCling::CreateListOfBaseClasses(TClass *cl)
const
4000 R__LOCKGUARD(gInterpreterMutex);
4004 TClingClassInfo *tci = (TClingClassInfo *)cl->GetClassInfo();
4006 TClingBaseClassInfo t(GetInterpreterImpl(), tci);
4007 TList *listOfBase =
new TList;
4010 if (t.IsValid() && t.Name()) {
4011 TClingBaseClassInfo *a =
new TClingBaseClassInfo(t);
4012 listOfBase->Add(
new TBaseClass((BaseClassInfo_t *)a, cl));
4016 cl->fBase = listOfBase;
4022 void TCling::LoadEnums(TListOfEnums& enumList)
const
4024 R__LOCKGUARD(gInterpreterMutex);
4027 TClass* cl = enumList.GetClass();
4029 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4032 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4035 if (
const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4036 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4038 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4039 const_cast< clang::DeclContext *
>(DC)->collectAllContexts(allDeclContexts);
4040 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4041 declIter != declEnd; ++declIter) {
4043 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4044 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4045 if (
const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4048 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4049 llvm::raw_string_ostream stream(buf);
4051 Policy.AnonymousTagLocations =
false;
4052 ED->getNameForDiagnostic(stream, Policy,
false);
4056 const char* name = buf.c_str();
4058 enumList.Get(ED, name);
4069 void TCling::LoadFunctionTemplates(TClass* cl)
const
4071 R__LOCKGUARD(gInterpreterMutex);
4074 TListOfFunctionTemplates* funcTempList;
4076 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4077 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(
false);
4080 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4081 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4084 if (
const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4085 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4087 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4088 const_cast< clang::DeclContext *
>(DC)->collectAllContexts(allDeclContexts);
4089 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4090 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4092 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4093 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4094 if (
const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4095 funcTempList->Get(FTD);
4105 std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl)
const
4107 TClingClassInfo *ci = (TClingClassInfo*)cl;
4108 return ci->GetUsingNamespaces();
4116 void TCling::CreateListOfDataMembers(TClass* cl)
const
4125 void TCling::CreateListOfMethods(TClass* cl)
const
4134 void TCling::UpdateListOfMethods(TClass* cl)
const
4143 void TCling::UpdateListOfDataMembers(TClass* cl)
const
4150 void TCling::CreateListOfMethodArgs(TFunction* m)
const
4152 R__LOCKGUARD(gInterpreterMutex);
4153 if (m->fMethodArgs) {
4156 TList *arglist =
new TList;
4157 TClingMethodArgInfo t(GetInterpreterImpl(), (TClingMethodInfo*)m->fInfo);
4160 TClingMethodArgInfo* a =
new TClingMethodArgInfo(t);
4161 arglist->Add(
new TMethodArg((MethodArgInfo_t*)a, m));
4164 m->fMethodArgs = arglist;
4173 TClass *TCling::GenerateTClass(
const char *classname, Bool_t emulation, Bool_t silent )
4185 Version_t version = 1;
4186 if (TClassEdit::IsSTLCont(classname)) {
4187 version = TClass::GetClass(
"TVirtualStreamerInfo")->GetClassVersion();
4189 TClass *cl =
new TClass(classname, version, silent);
4191 cl->SetBit(TClass::kIsEmulation);
4198 Version_t oldvers = cl->fClassVersion;
4199 if (oldvers == version && cl->GetClassInfo()) {
4201 Version_t newvers = oldvers;
4202 TClingClassInfo* cli = (TClingClassInfo*)cl->GetClassInfo();
4203 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4207 TClingMethodInfo mi = cli->GetMethod(
"Class_Version",
"", 0 ,
4209 TClingClassInfo::kInThisScope);
4210 if (!mi.IsValid()) {
4211 if (cl->TestBit(TClass::kIsTObject)) {
4212 Error(
"GenerateTClass",
4213 "Cannot find %s::Class_Version()! Class version might be wrong.",
4218 newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4220 if (newvers == -1) {
4223 if ((mi.Property() & kIsStatic)
4224 && !fInterpreter->isInSyntaxOnlyMode()) {
4226 TClingCallFunc callfunc(GetInterpreterImpl(), *fNormalizedCtxt);
4227 callfunc.SetFunc(&mi);
4228 newvers = callfunc.ExecInt(0);
4230 Error(
"GenerateTClass",
4231 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4235 if (newvers != oldvers) {
4236 cl->fClassVersion = newvers;
4237 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4252 static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4254 includes += info->FileName();
4256 const clang::ClassTemplateSpecializationDecl *templateCl
4257 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4259 for(
unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4260 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4261 if (arg.getKind() == clang::TemplateArgument::Type) {
4262 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4264 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4266 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4269 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4270 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4273 llvm::raw_string_ostream OS(Result);
4274 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4275 Warning(
"TCling::GenerateTClass",
"Missing header file for %s",OS.str().c_str());
4287 TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent )
4289 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4290 if (!info || !info->IsValid()) {
4291 Fatal(
"GenerateTClass",
"Requires a valid ClassInfo object");
4296 std::string classname;
4297 info->FullName(classname,*fNormalizedCtxt);
4298 if (TClassEdit::IsSTLCont(classname)) {
4300 Info(
"GenerateTClass",
"Will (try to) generate the compiled TClass for %s.",classname.c_str());
4304 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4306 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4308 cl = TClass::LoadClass(classnam.c_str(), silent);
4310 Error(
"GenerateTClass",
"Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4315 int version = TClass::GetClass(
"TVirtualStreamerInfo")->GetClassVersion();
4316 cl =
new TClass(classinfo, version, 0, 0, -1, -1, silent);
4317 cl->SetBit(TClass::kIsEmulation);
4322 cl =
new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4326 TClass::AddClassToDeclIdMap(((TClingClassInfo*)classinfo)->GetDeclId(), cl);
4345 Int_t TCling::GenerateDictionary(
const char* classes,
const char* includes ,
const char* )
4347 if (classes == 0 || classes[0] == 0) {
4348 Error(
"TCling::GenerateDictionary",
"Cannot generate dictionary without passing classes.");
4352 std::vector<std::string> listClasses;
4354 const char* current = classes, *prev = classes;
4358 if (*current ==
';') {
4359 listClasses.push_back(std::string(prev, current - prev));
4362 else if (*(current + 1) == 0) {
4363 listClasses.push_back(std::string(prev, current + 1 - prev));
4367 std::vector<std::string> listIncludes;
4371 const char* current = includes, *prev = includes;
4375 if (*current ==
';') {
4376 listIncludes.push_back(std::string(prev, current - prev));
4379 else if (*(current + 1) == 0) {
4380 listIncludes.push_back(std::string(prev, current + 1 - prev));
4385 return !TCling_GenerateDictionary(listClasses, listIncludes,
4386 std::vector<std::string>(), std::vector<std::string>());
4393 TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl,
const char *name)
const
4395 R__LOCKGUARD(gInterpreterMutex);
4397 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4400 d = cl->GetDataMember(name);
4407 if (
const ValueDecl* decl = (
const ValueDecl*) d){
4409 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,
"ioname",ioName);
4410 if (hasIoName && ioName != name)
return 0;
4422 using namespace clang;
4423 Sema& SemaR = fInterpreter->getSema();
4424 DeclarationName DName = &SemaR.Context.Idents.get(name);
4426 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4427 Sema::ForRedeclaration);
4430 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4431 cling::utils::Lookup::Named(&SemaR, R);
4433 LookupResult::Filter F = R.makeFilter();
4435 while (F.hasNext()) {
4436 NamedDecl *D = F.next();
4437 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4438 isa<IndirectFieldDecl>(D))
4444 if (R.isSingleResult())
4445 return R.getFoundDecl();
4453 TInterpreter::DeclId_t TCling::GetEnum(TClass *cl,
const char *name)
const
4455 R__LOCKGUARD(gInterpreterMutex);
4457 const clang::Decl* possibleEnum = 0;
4460 TClingClassInfo *cci = (TClingClassInfo*)cl->GetClassInfo();
4462 const clang::DeclContext* dc = 0;
4463 if (
const clang::Decl* D = cci->GetDecl()) {
4464 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4465 dc = dyn_cast<clang::RecordDecl>(D);
4471 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4472 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4474 Error(
"TCling::GetEnum",
"DeclContext not found for %s .\n", name);
4480 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4481 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4483 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4484 && isa<clang::EnumDecl>(possibleEnum)) {
4485 return possibleEnum;
4493 TInterpreter::DeclId_t TCling::GetDeclId(
const llvm::GlobalValue *gv )
const
4497 llvm::StringRef mangled_name = gv->getName();
4500 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4505 TClingClassInfo gcl(GetInterpreterImpl());
4506 d = gcl.GetDataMember(mangled_name.str().c_str());
4512 std::string scopename(demangled_name_c);
4513 free(demangled_name_c);
4519 std::string dataname;
4521 if (!strncmp(scopename.c_str(),
"typeinfo for ",
sizeof(
"typeinfo for ")-1)) {
4522 scopename.erase(0,
sizeof(
"typeinfo for ")-1);
4523 }
else if (!strncmp(scopename.c_str(),
"vtable for ",
sizeof(
"vtable for ")-1)) {
4524 scopename.erase(0,
sizeof(
"vtable for ")-1);
4527 std::string::size_type pos = scopename.rfind(
'(');
4528 if (pos != std::string::npos) {
4532 pos = scopename.rfind(
':');
4533 if (pos != std::string::npos) {
4534 if ((pos != 0) && (scopename[pos-1] ==
':')) {
4535 dataname = scopename.substr(pos+1);
4536 scopename.erase(pos-1);
4540 dataname = scopename;
4548 if (scopename.size()) {
4549 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4550 d = cl.GetDataMember(dataname.c_str());
4553 TClingClassInfo gcl(GetInterpreterImpl());
4554 d = gcl.GetDataMember(dataname.c_str());
4562 TInterpreter::DeclId_t TCling::GetDataMemberWithValue(
const void *ptrvalue)
const
4564 Error(
"GetDataMemberWithValue()",
"not implemented");
4571 TInterpreter::DeclId_t TCling::GetDataMemberAtAddr(
const void *addr)
const
4574 Error(
"GetDataMemberAtAddr()",
"not implemented");
4583 TString TCling::GetMangledName(TClass* cl,
const char* method,
4584 const char* params, Bool_t objectIsConst )
4586 R__LOCKGUARD(gInterpreterMutex);
4587 TClingCallFunc func(GetInterpreterImpl(), *fNormalizedCtxt);
4590 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4594 TClingClassInfo gcl(GetInterpreterImpl());
4596 func.SetFunc(&gcl, method, params, &offset);
4598 TClingMethodInfo* mi = (TClingMethodInfo*) func.FactoryMethod();
4600 TString mangled_name( mi->GetMangledName() );
4602 return mangled_name;
4610 TString TCling::GetMangledNameWithPrototype(TClass* cl,
const char* method,
4611 const char* proto, Bool_t objectIsConst ,
4612 EFunctionMatchMode mode )
4614 R__LOCKGUARD(gInterpreterMutex);
4616 return ((TClingClassInfo*)cl->GetClassInfo())->
4617 GetMethod(method, proto, objectIsConst, 0 , mode).GetMangledName();
4619 TClingClassInfo gcl(GetInterpreterImpl());
4620 return gcl.GetMethod(method, proto, objectIsConst, 0 , mode).GetMangledName();
4628 void* TCling::GetInterfaceMethod(TClass* cl,
const char* method,
4629 const char* params, Bool_t objectIsConst )
4631 R__LOCKGUARD(gInterpreterMutex);
4632 TClingCallFunc func(GetInterpreterImpl(), *fNormalizedCtxt);
4635 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4639 TClingClassInfo gcl(GetInterpreterImpl());
4641 func.SetFunc(&gcl, method, params, &offset);
4643 return (
void*) func.InterfaceMethod();
4650 TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl,
const char* method)
4652 R__LOCKGUARD(gInterpreterMutex);
4654 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4656 f = cl->GetMethod(method).GetDeclId();
4659 TClingClassInfo gcl(GetInterpreterImpl());
4660 f = gcl.GetMethod(method).GetDeclId();
4669 void TCling::GetFunctionOverloads(ClassInfo_t *cl,
const char *funcname,
4670 std::vector<DeclId_t>& res)
const
4672 clang::Sema& S = fInterpreter->getSema();
4673 clang::ASTContext& Ctx = S.Context;
4674 const clang::Decl* CtxDecl
4675 = cl ? (
const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4676 Ctx.getTranslationUnitDecl();
4677 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4678 const clang::DeclContext* DeclCtx = RecDecl;
4681 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4682 if (!DeclCtx) return;
4684 clang::DeclarationName DName;
4689 if (RecDecl->getNameAsString() == funcname) {
4690 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4691 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4692 }
else if (funcname[0] ==
'~' && RecDecl->getNameAsString() == funcname + 1) {
4693 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4694 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4696 DName = &Ctx.Idents.get(funcname);
4699 DName = &Ctx.Idents.get(funcname);
4702 clang::LookupResult R(S, DName, clang::SourceLocation(),
4703 Sema::LookupOrdinaryName, clang::Sema::ForRedeclaration);
4704 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
4705 if (R.empty())
return;
4707 res.reserve(res.size() + (R.end() - R.begin()));
4708 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
4710 if (
const clang::FunctionDecl* FD
4711 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
4712 if (!FD->getDescribedFunctionTemplate()) {
4724 void* TCling::GetInterfaceMethodWithPrototype(TClass* cl,
const char* method,
4726 Bool_t objectIsConst ,
4727 EFunctionMatchMode mode )
4729 R__LOCKGUARD(gInterpreterMutex);
4732 f = ((TClingClassInfo*)cl->GetClassInfo())->
4733 GetMethod(method, proto, objectIsConst, 0 , mode).InterfaceMethod(*fNormalizedCtxt);
4736 TClingClassInfo gcl(GetInterpreterImpl());
4737 f = gcl.GetMethod(method, proto, objectIsConst, 0 , mode).InterfaceMethod(*fNormalizedCtxt);
4747 TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl,
const char* method,
4749 Bool_t objectIsConst )
4751 R__LOCKGUARD(gInterpreterMutex);
4753 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4755 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 ).GetDeclId();
4758 TClingClassInfo gcl(GetInterpreterImpl());
4759 f = gcl.GetMethod(method, params, objectIsConst, 0 ).GetDeclId();
4769 TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl,
const char* method,
4771 Bool_t objectIsConst ,
4772 EFunctionMatchMode mode )
4774 R__LOCKGUARD(gInterpreterMutex);
4776 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4778 f = cl->GetMethod(method, proto, objectIsConst, 0 , mode).GetDeclId();
4781 TClingClassInfo gcl(GetInterpreterImpl());
4782 f = gcl.GetMethod(method, proto, objectIsConst, 0 , mode).GetDeclId();
4791 TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl,
const char* name)
4793 R__LOCKGUARD(gInterpreterMutex);
4795 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4797 f = cl->GetFunctionTemplate(name);
4800 TClingClassInfo gcl(GetInterpreterImpl());
4801 f = gcl.GetFunctionTemplate(name);
4814 void TCling::GetInterpreterTypeName(
const char* name, std::string &output, Bool_t full)
4818 R__LOCKGUARD(gInterpreterMutex);
4820 TClingClassInfo cl(GetInterpreterImpl(), name);
4821 if (!cl.IsValid()) {
4825 cl.FullName(output,*fNormalizedCtxt);
4830 TClassEdit::TSplitType splitname( cl.Name(), TClassEdit::kDropStd );
4831 splitname.ShortType(output, TClassEdit::kDropStd );
4847 void TCling::Execute(
const char*
function,
const char* params,
int* error)
4849 R__LOCKGUARD_CLING(gInterpreterMutex);
4851 *error = TInterpreter::kNoError;
4853 TClingClassInfo cl(GetInterpreterImpl());
4855 TClingCallFunc func(GetInterpreterImpl(), *fNormalizedCtxt);
4856 func.SetFunc(&cl,
function, params, &offset);
4871 void TCling::Execute(TObject* obj, TClass* cl,
const char* method,
4872 const char* params, Bool_t objectIsConst,
int* error)
4874 R__LOCKGUARD_CLING(gInterpreterMutex);
4876 *error = TInterpreter::kNoError;
4881 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
4883 TClingCallFunc func(GetInterpreterImpl(), *fNormalizedCtxt);
4884 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
4885 void* address = (
void*)((Long_t)addr + offset);
4891 void TCling::Execute(TObject* obj, TClass* cl,
const char* method,
4892 const char* params,
int* error)
4894 Execute(obj,cl,method,params,
false,error);
4905 void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
4906 TObjArray* params,
int* error)
4909 Error(
"Execute",
"No method was defined");
4912 TList* argList = method->GetListOfMethodArgs();
4915 Int_t nparms = argList->LastIndex() + 1;
4916 Int_t argc = params ? params->GetEntries() : 0;
4918 if (argc > nparms) {
4919 Error(
"Execute",
"Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
4922 if (nparms != argc) {
4927 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
4928 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
4932 Int_t firstDefault = -1;
4933 for (Int_t i = 0; i < nparms; i ++) {
4934 arg = (TMethodArg *) argList->At( i );
4935 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
4940 if (firstDefault >= 0) {
4941 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);
4943 Error(
"Execute",
"Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
4949 const char* listpar =
"";
4950 TString complete(10);
4954 for (Int_t i = 0; i < argc; i ++) {
4955 TMethodArg* arg = (TMethodArg*) argList->At(i);
4956 TClingTypeInfo type(GetInterpreterImpl(), arg->GetFullTypeName());
4957 TObjString* nxtpar = (TObjString*) next();
4961 if (strstr(type.TrueName(*fNormalizedCtxt),
"char")) {
4962 TString chpar(
'\"');
4963 chpar += (nxtpar->String()).ReplaceAll(
"\"",
"\\\"");
4970 complete += nxtpar->String();
4973 listpar = complete.Data();
4977 R__LOCKGUARD_CLING(gInterpreterMutex);
4979 *error = TInterpreter::kNoError;
4984 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
4985 TClingCallFunc func(GetInterpreterImpl(), *fNormalizedCtxt);
4986 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
4988 func.SetArgs(listpar);
4991 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetMethodDecl());
4992 Long_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
4993 void* address = (
void*)((Long_t)addr + offset);
4999 void TCling::ExecuteWithArgsAndReturn(TMethod* method,
void* address,
5000 const void* args[] ,
5005 Error(
"ExecuteWithArgsAndReturn",
"No method was defined");
5009 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5010 TClingCallFunc func(*minfo,*fNormalizedCtxt);
5011 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5017 Long_t TCling::ExecuteMacro(
const char* filename, EErrorCode* error)
5019 R__LOCKGUARD_CLING(fLockProcessLine ? gInterpreterMutex : 0);
5020 fCurExecutingMacros.push_back(filename);
5021 Long_t result = TApplication::ExecuteFile(filename, (
int*)error);
5022 fCurExecutingMacros.pop_back();
5030 const char* TCling::GetTopLevelMacroName()
const
5032 Warning(
"GetTopLevelMacroName",
"Must change return type!");
5033 return fCurExecutingMacros.back();
5077 const char* TCling::GetCurrentMacroName()
const
5079 #if defined(R__MUST_REVISIT)
5080 #if R__MUST_REVISIT(6,0)
5081 Warning(
"GetCurrentMacroName",
"Must change return type!");
5084 return fCurExecutingMacros.back();
5092 const char* TCling::TypeName(
const char* typeDesc)
5094 TTHREAD_TLS(
char*) t = 0;
5095 TTHREAD_TLS(
unsigned int) tlen = 0;
5097 unsigned int dlen = strlen(typeDesc);
5100 t =
new char[dlen + 1];
5103 const char* s, *template_start;
5104 if (!strstr(typeDesc,
"(*)(")) {
5105 s = strchr(typeDesc,
' ');
5106 template_start = strchr(typeDesc,
'<');
5107 if (!strcmp(typeDesc,
"long long")) {
5108 strlcpy(t, typeDesc, dlen + 1);
5110 else if (!strncmp(typeDesc,
"unsigned ", s + 1 - typeDesc)) {
5111 strlcpy(t, typeDesc, dlen + 1);
5117 else if (s && (template_start == 0 || (s < template_start))) {
5118 strlcpy(t, s + 1, dlen + 1);
5121 strlcpy(t, typeDesc, dlen + 1);
5125 strlcpy(t, typeDesc, dlen + 1);
5128 while (l > 0 && (t[l - 1] ==
'*' || t[l - 1] ==
'&')) {
5134 static bool requiresRootMap(
const char* rootmapfile, cling::Interpreter* interp)
5136 assert(rootmapfile && *rootmapfile);
5138 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5139 libName.consume_back(
".rootmap");
5141 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5150 int TCling::ReadRootmapFile(
const char *rootmapfile, TUniqueString *uniqueString)
5152 if (!(rootmapfile && *rootmapfile))
5155 if (!requiresRootMap(rootmapfile, GetInterpreterImpl()))
5159 const std::map<char, unsigned int> keyLenMap = {{
'c',6},{
'n',10},{
't',8},{
'h',7},{
'e',5},{
'v',4}};
5161 std::string rootmapfileNoBackslash(rootmapfile);
5163 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(),
'\\',
'/');
5166 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5170 uniqueString->Append(std::string(
"\n#line 1 \"Forward declarations from ") + rootmapfileNoBackslash +
"\"\n");
5172 std::ifstream file(rootmapfileNoBackslash);
5175 std::string lib_name;
5177 bool newFormat =
false;
5178 while (getline(file, line,
'\n')) {
5179 if (!newFormat && (line.compare(0, 8,
"Library.") == 0 || line.compare(0, 8,
"Declare.") == 0)) {
5185 if (line.compare(0, 9,
"{ decls }") == 0) {
5188 while (getline(file, line,
'\n')) {
5191 if (!uniqueString) {
5192 Error(
"ReadRootmapFile",
"Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5193 rootmapfileNoBackslash.c_str());
5196 uniqueString->Append(line);
5199 const char firstChar = line[0];
5200 if (firstChar ==
'[') {
5202 auto brpos = line.find(
']');
5203 if (brpos == string::npos)
5205 lib_name = line.substr(1, brpos - 1);
5207 while (lib_name[nspaces] ==
' ')
5210 lib_name.replace(0, nspaces,
"");
5212 TString lib_nameTstr(lib_name.c_str());
5213 TObjArray *tokens = lib_nameTstr.Tokenize(
" ");
5214 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5215 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5217 Info(
"ReadRootmapFile",
"new section for %s", lib_nameTstr.Data());
5219 Info(
"ReadRootmapFile",
"section for %s (library does not exist)", lib_nameTstr.Data());
5225 auto keyLenIt = keyLenMap.find(firstChar);
5226 if (keyLenIt == keyLenMap.end())
5228 unsigned int keyLen = keyLenIt->second;
5230 const char *keyname = line.c_str() + keyLen;
5232 Info(
"ReadRootmapFile",
"class %s in %s", keyname, lib_name.c_str());
5233 TEnvRec *isThere = fMapfile->Lookup(keyname);
5235 if (lib_name != isThere->GetValue()) {
5236 if (firstChar ==
'n') {
5238 Info(
"ReadRootmapFile",
"namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5239 isThere->GetValue());
5240 }
else if (firstChar ==
'h') {
5242 lib_name += isThere->GetValue();
5243 fMapfile->SetValue(keyname, lib_name.c_str());
5244 }
else if (!TClassEdit::IsSTLCont(keyname)) {
5245 Warning(
"ReadRootmapFile",
"%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5246 keyname, lib_name.c_str(), isThere->GetValue());
5250 Info(
"ReadRootmapFile",
"Key %s was already defined for %s", keyname, lib_name.c_str());
5253 fMapfile->SetValue(keyname, lib_name.c_str());
5271 void TCling::InitRootmapFile(
const char *name)
5273 assert(requiresRootMap(name, GetInterpreterImpl()) &&
"We have a module!");
5275 if (!requiresRootMap(name, GetInterpreterImpl()))
5278 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5280 fMapfile->SetRcName(name);
5282 TString sname =
"system";
5284 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5286 Int_t ret = ReadRootmapFile(s);
5288 fMapfile->ReadFile(s, kEnvGlobal);
5290 if (!gSystem->Getenv(
"ROOTENV_NO_HOME")) {
5291 s = gSystem->ConcatFileName(gSystem->HomeDirectory(), name);
5292 ret = ReadRootmapFile(s);
5294 fMapfile->ReadFile(s, kEnvUser);
5296 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5297 ret = ReadRootmapFile(name);
5299 fMapfile->ReadFile(name, kEnvLocal);
5302 ret = ReadRootmapFile(name);
5304 fMapfile->ReadFile(name, kEnvLocal);
5306 fMapfile->IgnoreDuplicates(ignore);
5311 using namespace clang;
5313 class ExtVisibleStorageAdder:
public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5319 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5320 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5325 nsDecl->setHasExternalVisibleStorage();
5326 fNSSet.insert(nsDecl);
5330 std::unordered_set<const NamespaceDecl*>& fNSSet;
5342 Int_t TCling::LoadLibraryMap(
const char* rootmapfile)
5344 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile, GetInterpreterImpl()))
5347 R__LOCKGUARD(gInterpreterMutex);
5351 fMapfile =
new TEnv();
5352 fMapfile->IgnoreDuplicates(kTRUE);
5353 fRootmapFiles =
new TObjArray;
5354 fRootmapFiles->SetOwner();
5355 InitRootmapFile(
".rootmap");
5361 TUniqueString uniqueString(1048576);
5365 TString ldpath = gSystem->GetDynamicPath();
5366 if (ldpath != fRootmapLoadPath) {
5367 fRootmapLoadPath = ldpath;
5369 TObjArray* paths = ldpath.Tokenize(
";");
5371 TObjArray* paths = ldpath.Tokenize(
":");
5374 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5375 d = ((TObjString *)paths->At(i))->GetString();
5378 for (Int_t j = 0; j < i; j++) {
5379 TString pd = ((TObjString *)paths->At(j))->GetString();
5386 void* dirp = gSystem->OpenDirectory(d);
5389 Info(
"LoadLibraryMap",
"%s", d.Data());
5392 while ((f1 = gSystem->GetDirEntry(dirp))) {
5394 if (f.EndsWith(
".rootmap")) {
5397 if (!gSystem->AccessPathName(p, kReadPermission)) {
5398 if (!fRootmapFiles->FindObject(f) && f !=
".rootmap") {
5400 Info(
"LoadLibraryMap",
" rootmap file: %s", p.Data());
5402 Int_t ret = ReadRootmapFile(p, &uniqueString);
5405 fRootmapFiles->Add(
new TNamed(gSystem->BaseName(f), p.Data()));
5408 fMapfile->ReadFile(p, kEnvGlobal);
5409 fRootmapFiles->Add(
new TNamed(f, p));
5418 if (f.BeginsWith(
"rootmap")) {
5422 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5423 Warning(
"LoadLibraryMap",
"please rename %s to end with \".rootmap\"", p.Data());
5428 gSystem->FreeDirectory(dirp);
5432 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5436 if (rootmapfile && *rootmapfile) {
5437 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5441 fRootmapFiles->Add(
new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5443 else if (res == -3) {
5445 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5446 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5447 fRootmapFiles->Add(
new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5448 fMapfile->IgnoreDuplicates(ignore);
5452 TIter next(fMapfile->GetTable());
5453 while ((rec = (TEnvRec*) next())) {
5454 TString cls = rec->GetName();
5455 if (!strncmp(cls.Data(),
"Library.", 8) && cls.Length() > 8) {
5457 TString libs = rec->GetValue();
5462 TObjArray* tokens = libs.Tokenize(delim);
5463 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5467 cls.ReplaceAll(
"@@",
"::");
5470 cls.ReplaceAll(
"-",
" ");
5472 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5474 Info(
"LoadLibraryMap",
"class %s in %s", cls.Data(), wlib);
5477 Info(
"LoadLibraryMap",
"class %s in %s (library does not exist)", cls.Data(), lib);
5483 else if (!strncmp(cls.Data(),
"Declare.", 8) && cls.Length() > 8) {
5487 cls.ReplaceAll(
"-",
" ");
5488 fInterpreter->declare(cls.Data());
5493 cling::Transaction* T =
nullptr;
5494 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5495 assert(cling::Interpreter::kSuccess == compRes &&
"A declaration in a rootmap could not be compiled");
5497 if (compRes!=cling::Interpreter::kSuccess){
5498 Warning(
"LoadLibraryMap",
5499 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5503 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5504 for (
auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5505 if (declIt->m_DGR.isSingleDecl()) {
5506 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5507 if (NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
5508 evsAdder.TraverseDecl(NSD);
5526 Int_t TCling::RescanLibraryMap()
5528 UnloadAllSharedLibraryMaps();
5538 Int_t TCling::ReloadAllSharedLibraryMaps()
5540 const TString sharedLibLStr = GetSharedLibs();
5541 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(
" ");
5542 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5543 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5544 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5545 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5546 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5550 TString rootMapBaseStr = sharedLibBaseStr;
5551 if (sharedLibBaseStr.EndsWith(
".dll")) {
5552 rootMapBaseStr.ReplaceAll(
".dll",
"");
5554 else if (sharedLibBaseStr.EndsWith(
".DLL")) {
5555 rootMapBaseStr.ReplaceAll(
".DLL",
"");
5557 else if (sharedLibBaseStr.EndsWith(
".so")) {
5558 rootMapBaseStr.ReplaceAll(
".so",
"");
5560 else if (sharedLibBaseStr.EndsWith(
".sl")) {
5561 rootMapBaseStr.ReplaceAll(
".sl",
"");
5563 else if (sharedLibBaseStr.EndsWith(
".dl")) {
5564 rootMapBaseStr.ReplaceAll(
".dl",
"");
5566 else if (sharedLibBaseStr.EndsWith(
".a")) {
5567 rootMapBaseStr.ReplaceAll(
".a",
"");
5570 Error(
"ReloadAllSharedLibraryMaps",
"Unknown library type %s", sharedLibBaseStr.Data());
5574 rootMapBaseStr +=
".rootmap";
5575 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5577 Error(
"ReloadAllSharedLibraryMaps",
"Could not find rootmap %s in path", rootMapBaseStr.Data());
5582 const Int_t status = LoadLibraryMap(rootMap);
5584 Error(
"ReloadAllSharedLibraryMaps",
"Error loading map %s", rootMap);
5599 Int_t TCling::UnloadAllSharedLibraryMaps()
5601 const TString sharedLibLStr = GetSharedLibs();
5602 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(
" ");
5603 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5604 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5605 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5606 UnloadLibraryMap(sharedLibBaseStr);
5617 Int_t TCling::UnloadLibraryMap(
const char* library)
5619 if (!fMapfile || !library || !*library) {
5622 TString libname(library);
5623 Ssiz_t idx = libname.Last(
'.');
5625 libname.Remove(idx);
5627 size_t len = libname.Length();
5629 TIter next(fMapfile->GetTable());
5630 R__LOCKGUARD(gInterpreterMutex);
5632 while ((rec = (TEnvRec *) next())) {
5633 TString cls = rec->GetName();
5634 if (cls.Length() > 2) {
5636 TString libs = rec->GetValue();
5641 TObjArray* tokens = libs.Tokenize(delim);
5642 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5643 if (!strncmp(cls.Data(),
"Library.", 8) && cls.Length() > 8) {
5647 cls.ReplaceAll(
"@@",
"::");
5650 cls.ReplaceAll(
"-",
" ");
5652 if (!strncmp(lib, libname.Data(), len)) {
5653 if (fMapfile->GetTable()->Remove(rec) == 0) {
5654 Error(
"UnloadLibraryMap",
"entry for <%s, %s> not found in library map table", cls.Data(), lib);
5662 TString library_rootmap(library);
5663 if (!library_rootmap.EndsWith(
".rootmap"))
5664 library_rootmap.Append(
".rootmap");
5666 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5667 fRootmapFiles->Remove(mfile);
5670 fRootmapFiles->Compress();
5679 Int_t TCling::SetClassSharedLibs(
const char *cls,
const char *libs)
5684 TString key = TString(
"Library.") + cls;
5687 key.ReplaceAll(
"::",
"@@");
5690 key.ReplaceAll(
" ",
"-");
5692 R__LOCKGUARD(gInterpreterMutex);
5694 fMapfile =
new TEnv();
5695 fMapfile->IgnoreDuplicates(kTRUE);
5697 fRootmapFiles =
new TObjArray;
5698 fRootmapFiles->SetOwner();
5700 InitRootmapFile(
".rootmap");
5703 fMapfile->SetValue(cls, libs);
5711 TClass *TCling::GetClass(
const std::type_info& typeinfo, Bool_t load)
const
5714 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
5716 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
5717 free(demangled_name);
5725 Int_t TCling::AutoLoad(
const std::type_info& typeinfo, Bool_t knowDictNotLoaded )
5727 assert(IsClassAutoloadingEnabled() &&
"Calling when autoloading is off!");
5730 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
5735 std::string demangled_name(demangled_name_c);
5736 free(demangled_name_c);
5740 TClassEdit::TSplitType splitname( demangled_name.c_str(), (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
5741 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
5746 Int_t result = AutoLoad(demangled_name.c_str());
5748 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
5749 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
5759 Int_t TCling::AutoLoad(
const char *cls, Bool_t knowDictNotLoaded )
5765 if (!IsClassAutoloadingEnabled()) {
5768 Info(
"TCling::AutoLoad",
"Explicitly disabled (the class name is %s)", cls);
5773 assert(IsClassAutoloadingEnabled() &&
"Calling when autoloading is off!");
5775 R__LOCKGUARD(gInterpreterMutex);
5777 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
5788 Info(
"TCling::AutoLoad",
5789 "Trying to autoload for %s", cls);
5792 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
5794 Info(
"TCling::AutoLoad",
5795 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
5800 SuspendAutoloadingRAII autoLoadOff(
this);
5802 if (fAutoLoadCallBack) {
5803 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
5809 TString deplibs = GetClassSharedLibs(cls);
5810 if (!deplibs.IsNull()) {
5812 TObjArray* tokens = deplibs.Tokenize(delim);
5813 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
5814 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
5815 if (gROOT->LoadClass(cls, deplib) == 0) {
5817 Info(
"TCling::AutoLoad",
5818 "loaded dependent library %s for %s", deplib, cls);
5822 Error(
"TCling::AutoLoad",
5823 "failure loading dependent library %s for %s",
5827 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5828 if (lib && lib[0]) {
5829 if (gROOT->LoadClass(cls, lib) == 0) {
5831 Info(
"TCling::AutoLoad",
5832 "loaded library %s for %s", lib, cls);
5837 Error(
"TCling::AutoLoad",
5838 "failure loading library %s for %s", lib, cls);
5850 static cling::Interpreter::CompilationResult ExecAutoParse(
const char *what,
5852 cling::Interpreter *interpreter)
5854 std::string code = gNonInterpreterClassDef ;
5861 code += (
"#include \"");
5865 code += (
"#ifdef __ROOTCLING__\n"
5866 "#undef __ROOTCLING__\n"
5867 + gInterpreterClassDef +
5870 cling::Interpreter::CompilationResult cr;
5876 Sema &SemaR = interpreter->getSema();
5877 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
5878 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
5880 #if defined(R__MUST_REVISIT)
5881 #if R__MUST_REVISIT(6,2)
5882 Warning(
"TCling::RegisterModule",
"Diagnostics suppression should be gone by now.");
5886 cr = interpreter->parseForModule(code);
5899 UInt_t TCling::AutoParseImplRecurse(
const char *cls,
bool topLevel)
5904 Int_t nHheadersParsed = 0;
5905 unsigned long offset = 0;
5906 if (strncmp(cls,
"const ", 6) == 0) {
5911 bool skipFirstEntry =
false;
5912 std::vector<std::string> autoparseKeys;
5913 if (strchr(cls,
'<')) {
5915 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
5919 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
5924 TString templateName(autoparseKeys[0]);
5925 auto tokens = templateName.Tokenize(
"::");
5926 clang::NamedDecl* previousScopeAsNamedDecl =
nullptr;
5927 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
5928 if (TClassEdit::IsStdClass(cls + offset))
5929 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
5930 auto nTokens = tokens->GetEntries();
5931 for (Int_t tk = 0; tk < nTokens; ++tk) {
5932 auto scopeObj = tokens->UncheckedAt(tk);
5933 auto scopeName = ((TObjString*) scopeObj)->String().Data();
5934 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
5936 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl)
break;
5937 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
5938 if (!previousScopeAsContext)
break;
5942 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
5943 if (
auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
5944 if (
auto templatedDecl = templateDecl->getTemplatedDecl()) {
5945 skipFirstEntry = templatedDecl->hasDefinition();
5952 if (topLevel) autoparseKeys.emplace_back(cls);
5954 for (
const auto & apKeyStr : autoparseKeys) {
5955 if (skipFirstEntry) {
5956 skipFirstEntry=
false;
5959 if (apKeyStr.empty())
continue;
5960 const char *apKey = apKeyStr.c_str();
5961 std::size_t normNameHash(fStringHashFunction(apKey));
5964 Info(
"TCling::AutoParse",
5965 "Starting autoparse for %s\n", apKey);
5967 if (fLookedUpClasses.insert(normNameHash).second) {
5968 auto const &iter = fClassesHeadersMap.find(normNameHash);
5969 if (iter != fClassesHeadersMap.end()) {
5970 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
5971 fTransactionHeadersMap.insert({T,normNameHash});
5972 auto const &hNamesPtrs = iter->second;
5974 Info(
"TCling::AutoParse",
5975 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
5977 for (
auto & hName : hNamesPtrs) {
5978 if (fParsedPayloadsAddresses.count(hName) == 1)
continue;
5979 if (0 != fPayloads.count(normNameHash)) {
5980 float initRSSval=0.f, initVSIZEval=0.f;
5982 (void) initVSIZEval;
5985 "Parsing full payload for %s", apKey);
5987 gSystem->GetProcInfo(&info);
5988 initRSSval = 1e-3*info.fMemResident;
5989 initVSIZEval = 1e-3*info.fMemVirtual;
5991 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
5992 if (cRes != cling::Interpreter::kSuccess) {
5993 if (hName[0] ==
'\n')
5994 Error(
"AutoParse",
"Error parsing payload code for class %s with content:\n%s", apKey, hName);
5996 fParsedPayloadsAddresses.insert(hName);
6000 gSystem->GetProcInfo(&info);
6001 float endRSSval = 1e-3*info.fMemResident;
6002 float endVSIZEval = 1e-3*info.fMemVirtual;
6003 Info(
"Autoparse",
">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6004 Info(
"Autoparse",
">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6007 }
else if (!IsLoaded(hName)) {
6010 "Parsing single header %s", hName);
6012 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6013 if (cRes != cling::Interpreter::kSuccess) {
6014 Error(
"AutoParse",
"Error parsing headerfile %s for class %s.", hName, apKey);
6026 if (strchr(apKey,
'<')) {
6027 nHheadersParsed += AutoParseImplRecurse(apKey,
false);
6033 return nHheadersParsed;
6041 Int_t TCling::AutoParse(
const char *cls)
6043 if (llvm::StringRef(cls).contains(
"(lambda)"))
6046 if (!fHeaderParsingOnDemand || fIsAutoParsingSuspended) {
6047 if (fClingCallbacks->IsAutoloadingEnabled()) {
6048 return AutoLoad(cls);
6054 R__LOCKGUARD(gInterpreterMutex);
6057 Info(
"TCling::AutoParse",
6058 "Trying to autoparse for %s", cls);
6062 if (fClingCallbacks->IsAutoloadingEnabled()
6063 && !gClassTable->GetDictNorm(cls)) {
6065 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6066 fInterpreter->getSema());
6067 AutoLoad(cls,
true );
6071 SuspendAutoloadingRAII autoLoadOff(
this);
6074 SuspendAutoParsing autoParseRAII(
this);
6076 Int_t nHheadersParsed = AutoParseImplRecurse(cls,
true);
6078 ProcessClassesToUpdate();
6080 return nHheadersParsed > 0 ? 1 : 0;
6086 bool TCling::LibraryLoadingFailed(
const std::string& errmessage,
const std::string& libStem,
bool permanent,
bool resolved)
6088 StringRef errMsg(errmessage);
6089 if (errMsg.contains(
"undefined symbol: ")) {
6091 std::string mangled_name = std::string(errMsg.split(
"undefined symbol: ").second);
6092 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6093 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6094 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6099 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6107 static uint32_t GNUHash(StringRef S) {
6110 H = (H << 5) + H + C;
6114 static StringRef GetGnuHashSection(llvm::object::ObjectFile *file) {
6115 for (
auto S : file->sections()) {
6118 if (name ==
".gnu.hash") {
6120 S.getContents(content);
6135 static bool MayExistInObjectFile(llvm::object::ObjectFile *soFile, uint32_t hash) {
6136 if (!soFile->isELF())
6140 const int bits = 8 * soFile->getBytesInAddress();
6142 StringRef contents = GetGnuHashSection(soFile);
6143 if (contents.size() < 16)
6146 const char* hashContent = contents.data();
6149 uint32_t maskWords = *
reinterpret_cast<const uint32_t *
>(hashContent + 8);
6150 uint32_t shift2 = *
reinterpret_cast<const uint32_t *
>(hashContent + 12);
6151 uint32_t hash2 = hash >> shift2;
6152 uint32_t n = (hash / bits) % maskWords;
6154 const char *bloomfilter = hashContent + 16;
6155 const char *hash_pos = bloomfilter + n*(bits/8);
6156 uint64_t word = *
reinterpret_cast<const uint64_t *
>(hash_pos);
6157 uint64_t bitmask = ( (1ULL << (hash % bits)) | (1ULL << (hash2 % bits)));
6158 return (bitmask & word) == bitmask;
6163 static bool FindSymbol(
const std::string &library_filename,
6164 const std::string &mangled_name,
unsigned IgnoreSymbolFlags = 0)
6166 auto ObjF = llvm::object::ObjectFile::createObjectFile(ROOT::TMetaUtils::GetRealPath(library_filename));
6169 Warning(
"TCling__FindSymbol",
"Failed to read object file %s", library_filename.c_str());
6173 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
6175 uint32_t hashedMangle = GNUHash(mangled_name);
6177 if (!MayExistInObjectFile(BinObjFile, hashedMangle))
6180 for (
const auto &S : BinObjFile->symbols()) {
6181 uint32_t Flags = S.getFlags();
6183 if (Flags & IgnoreSymbolFlags)
6195 llvm::Expected<StringRef> SymNameErr = S.getName();
6197 Warning(
"TCling__FindSymbol",
"Failed to read symbol %s", mangled_name.c_str());
6201 if (SymNameErr.get() == mangled_name) {
6203 Info(
"TCling__FindSymbol",
"Symbol %s found in %s\n",
6204 mangled_name.c_str(), library_filename.c_str());
6209 if (!BinObjFile->isELF())
6213 const auto *ElfObj = cast<llvm::object::ELFObjectFileBase>(BinObjFile);
6215 for (
const auto &S : ElfObj->getDynamicSymbolIterators()) {
6216 uint32_t Flags = S.getFlags();
6218 if (Flags & llvm::object::SymbolRef::SF_Undefined)
6230 llvm::Expected<StringRef> SymNameErr = S.getName();
6232 Warning(
"TCling__FindSymbol",
"Failed to read symbol %s", mangled_name.c_str());
6236 if (SymNameErr.get() == mangled_name)
6243 static std::string ResolveSymbol(
const std::string& mangled_name,
6244 cling::Interpreter *interp,
6245 bool searchSystem =
true) {
6246 assert(!mangled_name.empty());
6247 using namespace llvm::sys::path;
6248 using namespace llvm::sys::fs;
6250 R__LOCKGUARD(gInterpreterMutex);
6252 static bool sFirstRun =
true;
6253 static bool sFirstSystemLibrary =
true;
6260 using LibraryPath = std::pair<uint32_t, std::string>;
6261 using LibraryPaths = std::vector<LibraryPath>;
6262 using BasePaths = std::vector<std::string>;
6263 static LibraryPaths sLibraries;
6264 static BasePaths sPaths;
6265 static LibraryPaths sQueriedLibraries;
6268 static LibraryPaths sSysLibraries;
6271 TCling__FindLoadedLibraries(sLibraries, sPaths, *interp,
false);
6275 auto GetLibFileName = [](
const LibraryPath &P,
const BasePaths &BaseP) {
6276 llvm::SmallString<512> Vec(BaseP[P.first]);
6277 llvm::sys::path::append(Vec, StringRef(P.second));
6278 return Vec.str().str();
6281 if (!sQueriedLibraries.empty()) {
6285 for (
const LibraryPath &P : sQueriedLibraries) {
6286 const std::string LibName = GetLibFileName(P, sPaths);
6287 if (!gCling->IsLibraryLoaded(LibName.c_str()))
6290 sLibraries.erase(std::remove(sLibraries.begin(), sLibraries.end(), P), sLibraries.end());
6291 if (!sSysLibraries.empty())
6292 sSysLibraries.erase(std::remove(sSysLibraries.begin(), sSysLibraries.end(), P), sSysLibraries.end());
6297 TCling__FindLoadedLibraries(sLibraries, sPaths, *interp,
false);
6302 for (
const LibraryPath &P : sLibraries) {
6303 const std::string LibName = GetLibFileName(P, sPaths);
6309 if (FindSymbol(LibName, mangled_name,
6310 llvm::object::SymbolRef::SF_Undefined |
6311 llvm::object::SymbolRef::SF_Weak)) {
6312 sQueriedLibraries.push_back(P);
6321 if (sFirstSystemLibrary) {
6322 TCling__FindLoadedLibraries(sSysLibraries, sPaths, *interp,
true);
6323 sFirstSystemLibrary =
false;
6326 for (
const LibraryPath &P : sSysLibraries) {
6327 const std::string LibName = GetLibFileName(P, sPaths);
6329 if (FindSymbol(LibName, mangled_name,
6330 llvm::object::SymbolRef::SF_Undefined |
6331 llvm::object::SymbolRef::SF_Weak)) {
6332 sQueriedLibraries.push_back(P);
6340 static void* LazyFunctionCreatorAutoloadForModule(
const std::string &mangled_name,
6341 cling::Interpreter *interp) {
6345 std::string maybe_prefixed_mangled_name = mangled_name;
6347 assert(!llvm::StringRef(mangled_name).startswith(
"__") &&
"Already added!");
6348 maybe_prefixed_mangled_name =
"_" + maybe_prefixed_mangled_name;
6351 std::string LibName = ResolveSymbol(maybe_prefixed_mangled_name, interp);
6352 if (LibName.empty())
6355 if (gSystem->Load(LibName.c_str(),
"",
false) < 0)
6356 Error(
"TCling__LazyFunctionCreatorAutoloadForModule",
6357 "Failed to load library %s", LibName.c_str());
6359 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6366 void* TCling::LazyFunctionCreatorAutoload(
const std::string& mangled_name) {
6367 if (fCxxModulesEnabled)
6368 return LazyFunctionCreatorAutoloadForModule(mangled_name, GetInterpreterImpl());
6373 if (!fRegisterModuleDyLibs.empty()) {
6374 if (
void* addr = dlsym(fRegisterModuleDyLibs.back(),
6375 mangled_name.c_str())) {
6381 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6386 std::string name(demangled_name_c);
6387 free(demangled_name_c);
6395 std::string::size_type pos = name.find(
"__thiscall ");
6396 if (pos != std::string::npos) {
6397 name.erase(0, pos +
sizeof(
"__thiscall ")-1);
6399 pos = name.find(
"__cdecl ");
6400 if (pos != std::string::npos) {
6401 name.erase(0, pos +
sizeof(
"__cdecl ")-1);
6403 if (!strncmp(name.c_str(),
"typeinfo for ",
sizeof(
"typeinfo for ")-1)) {
6404 name.erase(0,
sizeof(
"typeinfo for ")-1);
6405 }
else if (!strncmp(name.c_str(),
"vtable for ",
sizeof(
"vtable for ")-1)) {
6406 name.erase(0,
sizeof(
"vtable for ")-1);
6407 }
else if (!strncmp(name.c_str(),
"operator",
sizeof(
"operator")-1)
6408 && !isalnum(name[
sizeof(
"operator")])) {
6410 name.erase(0,
sizeof(
"operator")-1);
6411 pos = name.rfind(
'(');
6412 if (pos != std::string::npos) {
6413 name.erase(0, pos + 1);
6414 pos = name.find(
",");
6415 if (pos != std::string::npos) {
6419 pos = name.rfind(
" const");
6420 if (pos != std::string::npos) {
6421 name.erase(pos, strlen(
" const"));
6423 while (!name.empty() && strchr(
"&*", name.back()))
6424 name.erase(name.length() - 1);
6427 TClassEdit::FunctionSplitInfo fsi;
6428 TClassEdit::SplitFunction(name, fsi);
6429 name = fsi.fScopeName;
6433 TString libs = GetClassSharedLibs(name.c_str());
6434 if (libs.IsNull()) {
6443 while (libs.Tokenize(lib, posLib)) {
6444 if (gSystem->Load(lib,
"", kFALSE ) < 0) {
6453 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6460 Bool_t TCling::IsAutoLoadNamespaceCandidate(
const clang::NamespaceDecl* nsDecl)
6462 return fNSFromRootmaps.count(nsDecl) != 0;
6468 void TCling::RefreshClassInfo(TClass *cl,
const clang::NamedDecl *def,
bool alias)
6471 TClingClassInfo *cci = ((TClingClassInfo *)cl->fClassInfo);
6475 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6476 if (!oldDef || (def && def != oldDef)) {
6478 TClass::RemoveClassDeclId(cci->GetDeclId());
6481 cci->Init(*cci->GetType());
6482 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6485 }
else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6490 if (!alias && def !=
nullptr)
6491 cl->fClassInfo = (ClassInfo_t *)
new TClingClassInfo(GetInterpreterImpl(), def);
6493 cl->fClassInfo = (ClassInfo_t *)
new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6494 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6496 if (cl->fState != TClass::kHasTClassInit) {
6498 cl->fState = TClass::kInterpreted;
6499 cl->ResetBit(TClass::kIsEmulation);
6501 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6503 delete ((TClingClassInfo *)cl->fClassInfo);
6504 cl->fClassInfo =
nullptr;
6511 void TCling::UpdateClassInfoWithDecl(
const NamedDecl* ND)
6513 const TagDecl *td = dyn_cast<TagDecl>(ND);
6514 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6515 const NamedDecl *canon =
nullptr;
6520 canon = tdDef = td->getDefinition();
6524 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6530 auto declName = tdDef->getNameAsString();
6536 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6541 clang::QualType type(tdDef->getTypeForDecl(), 0);
6542 ROOT::TMetaUtils::GetNormalizedName(name, type, *fInterpreter, *fNormalizedCtxt);
6544 canon = ns->getCanonicalDecl();
6545 name = ND->getQualifiedNameAsString();
6547 name = ND->getQualifiedNameAsString();
6553 SuspendAutoloadingRAII autoLoadOff(
this);
6556 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6557 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6558 RefreshClassInfo(cl, canon,
false);
6569 void TCling::UpdateClassInfo(
char* item, Long_t tagnum)
6575 void TCling::UpdateClassInfoWork(
const char* item)
6584 void TCling::UpdateAllCanvases()
6586 TIter next(gROOT->GetListOfCanvases());
6587 TVirtualPad* canvas;
6588 while ((canvas = (TVirtualPad*)next())) {
6595 void TCling::UpdateListsOnCommitted(
const cling::Transaction &T) {
6596 std::set<TClass*> modifiedTClasses;
6599 if (!HandleNewTransaction(T))
return;
6601 bool isTUTransaction =
false;
6602 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6603 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6604 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6607 isTUTransaction =
true;
6611 std::set<const void*> TransactionDeclSet;
6612 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6613 const clang::Decl* WrapperFD = T.getWrapperFD();
6614 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6616 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6617 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6620 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6621 DE = I->m_DGR.end(); DI != DE; ++DI) {
6622 if (*DI == WrapperFD)
6624 TransactionDeclSet.insert(*DI);
6625 ((TCling*)gCling)->HandleNewDecl(*DI,
false, modifiedTClasses);
6632 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6633 E = T.deserialized_decls_end(); I != E; ++I) {
6634 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6635 DE = I->m_DGR.end(); DI != DE; ++DI)
6636 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6638 ((TCling*)gCling)->HandleNewDecl(*DI,
true,
6652 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6653 std::vector<TClass*>::iterator it;
6654 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6655 ((TCling*)gCling)->GetModTClasses().begin(),
6656 ((TCling*)gCling)->GetModTClasses().end(),
6657 modifiedTClassesDiff.begin());
6658 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6661 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6662 modifiedTClassesDiff.end());
6663 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6664 E = modifiedTClassesDiff.end(); I != E; ++I) {
6666 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6670 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6672 ((TCling*)gCling)->GetModTClasses().erase(*I);
6679 void TCling::UpdateListsOnUnloaded(
const cling::Transaction &T)
6681 HandleNewTransaction(T);
6683 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6684 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6685 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6686 (TListOfEnums *)gROOT->GetListOfEnums());
6688 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6689 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6691 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6693 if (I->m_Call == cling::Transaction::kCCINone) {
6694 UpdateListsOnUnloaded(*(*iNested));
6699 for (
auto &D : I->m_DGR)
6700 InvalidateCachedDecl(Lists, D);
6706 void TCling::InvalidateGlobal(
const Decl *D) {
6707 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6708 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6709 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6710 (TListOfEnums *)gROOT->GetListOfEnums());
6711 InvalidateCachedDecl(Lists, D);
6721 void TCling::InvalidateCachedDecl(
const std::tuple<TListOfDataMembers*,
6723 TListOfFunctionTemplates*,
6724 TListOfEnums*> &Lists,
const Decl *D) {
6725 if (D->isFromASTFile())
6728 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6729 TListOfFunctions &LOF = *(std::get<1>(Lists));
6730 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6731 TListOfEnums &LOE = *(std::get<3>(Lists));
6733 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6734 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6735 if (LODM.GetClass())
6736 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6738 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6739 }
else if (isa<FunctionDecl>(D)) {
6740 RemoveAndInvalidateObject(LOF, LOF.Find((TDictionary::DeclId_t)D));
6741 }
else if (isa<FunctionTemplateDecl>(D)) {
6742 RemoveAndInvalidateObject(LOFT, LOFT.Get((TDictionary::DeclId_t)D));
6743 }
else if (isa<EnumDecl>(D)) {
6744 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6749 for (TIter I = E->GetConstants();
auto EC = (TEnumConstant *)I(); )
6750 RemoveAndInvalidateObject(LODM,
6751 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6753 RemoveAndInvalidateObject(LOE, E);
6754 }
else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6755 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6758 std::vector<TClass *> Classes;
6759 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6761 for (
auto &C : Classes) {
6762 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6763 (TListOfFunctions *)C->GetListOfMethods(),
6764 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6765 (TListOfEnums *)C->GetListOfEnums());
6766 for (
auto &I : cast<DeclContext>(D)->decls())
6767 InvalidateCachedDecl(Lists, I);
6770 if (D->getKind() != Decl::Namespace
6771 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6772 C->ResetClassInfo();
6781 void TCling::TransactionRollback(
const cling::Transaction &T) {
6782 auto const &triter = fTransactionHeadersMap.find(&T);
6783 if (triter != fTransactionHeadersMap.end()) {
6784 std::size_t normNameHash = triter->second;
6786 fLookedUpClasses.erase(normNameHash);
6788 auto const &iter = fClassesHeadersMap.find(normNameHash);
6789 if (iter != fClassesHeadersMap.end()) {
6790 auto const &hNamesPtrs = iter->second;
6791 for (
auto &hName : hNamesPtrs) {
6793 Info(
"TransactionRollback",
6794 "Restoring ability to autoaparse: %s", hName);
6796 fParsedPayloadsAddresses.erase(hName);
6804 void TCling::LibraryLoaded(
const void* dyLibHandle,
const char* canonicalName) {
6810 void TCling::LibraryUnloaded(
const void* dyLibHandle,
const char* canonicalName) {
6811 fPrevLoadedDynLibInfo = 0;
6818 const char* TCling::GetSharedLibs()
6820 UpdateListOfLoadedSharedLibraries();
6824 static std::string GetClassSharedLibsForModule(
const char *cls, cling::LookupHelper &LH)
6829 using namespace clang;
6830 if (
const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6832 if (!D->isFromASTFile()) {
6834 Warning(
"GetClassSharedLibsForModule",
"Decl found for %s is not part of a module", cls);
6837 class ModuleCollector :
public ConstDeclVisitor<ModuleCollector> {
6838 llvm::DenseSet<Module *> &m_TopLevelModules;
6841 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6842 void Collect(
const Decl *D) { Visit(D); }
6844 void VisitDecl(
const Decl *D)
6854 if (!D->hasOwningModule())
6856 if (Module *M = D->getOwningModule()->getTopLevelModule())
6857 m_TopLevelModules.insert(M);
6860 void VisitTemplateArgument(
const TemplateArgument &TA)
6862 switch (TA.getKind()) {
6863 case TemplateArgument::Null:
6864 case TemplateArgument::Integral:
6865 case TemplateArgument::Pack:
6866 case TemplateArgument::NullPtr:
6867 case TemplateArgument::Expression:
6868 case TemplateArgument::Template:
6869 case TemplateArgument::TemplateExpansion:
return;
6870 case TemplateArgument::Type:
6871 if (
const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
6872 return Visit(TagTy->getDecl());
6874 case TemplateArgument::Declaration:
return Visit(TA.getAsDecl());
6876 llvm_unreachable(
"Invalid TemplateArgument::Kind!");
6879 void VisitClassTemplateSpecializationDecl(
const ClassTemplateSpecializationDecl *CTSD)
6881 if (CTSD->getOwningModule())
6884 VisitDecl(CTSD->getSpecializedTemplate());
6885 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
6886 for (
const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
6887 VisitTemplateArgument(*Arg);
6892 llvm::DenseSet<Module *> TopLevelModules;
6893 ModuleCollector m(TopLevelModules);
6896 for (
auto M : TopLevelModules) {
6899 if (!M->LinkLibraries.size())
6902 if (M->Name ==
"Core")
6904 assert(M->LinkLibraries.size() == 1);
6905 if (!result.empty())
6907 result += M->LinkLibraries[0].Library;
6920 const char* TCling::GetClassSharedLibs(
const char* cls)
6922 if (fCxxModulesEnabled) {
6923 llvm::StringRef className = cls;
6929 if (className.contains(
"(lambda)"))
6932 SuspendAutoloadingRAII AutoloadingDisabled(
this);
6933 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
6934 std::string libs = GetClassSharedLibsForModule(cls, LH);
6935 if (!libs.empty()) {
6936 fAutoLoadLibStorage.push_back(libs);
6937 return fAutoLoadLibStorage.back().c_str();
6941 if (!cls || !*cls) {
6946 TEnvRec* libs_record = 0;
6947 libs_record = fMapfile->Lookup(cls);
6949 const char* libs = libs_record->GetValue();
6950 return (*libs) ? libs : 0;
6954 TString c = TString(
"Library.") + cls;
6957 c.ReplaceAll(
"::",
"@@");
6960 c.ReplaceAll(
" ",
"-");
6964 TEnvRec* libs_record = 0;
6965 libs_record = fMapfile->Lookup(c);
6967 const char* libs = libs_record->GetValue();
6968 return (*libs) ? libs : 0;
6981 static std::string GetSharedLibImmediateDepsSlow(std::string lib,
6982 cling::Interpreter *interp,
6983 bool skipLoadedLibs =
true)
6985 TString LibFullPath(lib);
6986 if (!llvm::sys::path::is_absolute(lib)) {
6987 if (!gSystem->FindDynamicLibrary(LibFullPath,
true)) {
6988 Error(
"TCling__GetSharedLibImmediateDepsSlow",
"Cannot find library '%s'", lib.c_str());
6992 lib = llvm::sys::path::filename(lib);
6995 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
6997 Warning(
"TCling__GetSharedLibImmediateDepsSlow",
"Failed to read object file %s", lib.c_str());
7001 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7003 std::set<string> DedupSet;
7004 std::string Result = lib +
' ';
7005 for (
const auto &S : BinObjFile->symbols()) {
7006 uint32_t Flags = S.getFlags();
7007 if (Flags & llvm::object::SymbolRef::SF_Undefined) {
7008 llvm::Expected<StringRef> SymNameErr = S.getName();
7010 Warning(
"GetSharedLibDepsForModule",
"Failed to read symbol");
7013 llvm::StringRef SymName = SymNameErr.get();
7014 if (SymName.empty())
7017 if (BinObjFile->isELF()) {
7021 if (SymName.contains(
"@@GLIBCXX") || SymName.contains(
"@@CXXABI") ||
7022 SymName.contains(
"@@GLIBC") || SymName.contains(
"@@GCC"))
7030 if (SymName ==
"_Jv_RegisterClasses" ||
7031 SymName ==
"_ITM_deregisterTMCloneTable" ||
7032 SymName ==
"_ITM_registerTMCloneTable")
7037 if (skipLoadedLibs && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName))
7040 std::string found = ResolveSymbol(SymName, interp,
false);
7046 if (!found.empty()) {
7047 std::string cand = llvm::sys::path::filename(found).str();
7048 if (!DedupSet.insert(cand).second)
7051 Result += cand +
' ';
7068 const char* TCling::GetSharedLibDeps(
const char* lib,
bool useDyld)
7071 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7072 if (!libs.empty()) {
7073 fAutoLoadLibStorage.push_back(libs);
7074 return fAutoLoadLibStorage.back().c_str();
7078 if (!fMapfile || !lib || !lib[0]) {
7081 TString libname(lib);
7082 Ssiz_t idx = libname.Last(
'.');
7084 libname.Remove(idx);
7087 TIter next(fMapfile->GetTable());
7088 size_t len = libname.Length();
7089 while ((rec = (TEnvRec*) next())) {
7090 const char* libs = rec->GetValue();
7091 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7092 && (!libs[len] || libs[len] ==
' ' || libs[len] ==
'.')) {
7103 Bool_t TCling::IsErrorMessagesEnabled()
const
7105 #if defined(R__MUST_REVISIT)
7106 #if R__MUST_REVISIT(6,2)
7107 Warning(
"IsErrorMessagesEnabled",
"Interface not available yet.");
7117 Bool_t TCling::SetErrorMessages(Bool_t enable)
7119 #if defined(R__MUST_REVISIT)
7120 #if R__MUST_REVISIT(6,2)
7121 Warning(
"SetErrorMessages",
"Interface not available yet.");
7124 return TCling::IsErrorMessagesEnabled();
7131 const char* TCling::GetIncludePath()
7133 R__LOCKGUARD(gInterpreterMutex);
7137 llvm::SmallVector<std::string, 10> includePaths;
7139 fInterpreter->GetIncludePaths(includePaths,
false,
true);
7140 if (
const size_t nPaths = includePaths.size()) {
7141 assert(!(nPaths & 1) &&
"GetIncludePath, number of paths and options is not equal");
7143 for (
size_t i = 0; i < nPaths; i += 2) {
7145 fIncludePath.Append(
' ');
7146 fIncludePath.Append(includePaths[i].c_str());
7148 if (includePaths[i] !=
"-I")
7149 fIncludePath.Append(
' ');
7150 fIncludePath.Append(
'"');
7151 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7152 fIncludePath.Append(
'"');
7156 return fIncludePath;
7162 const char* TCling::GetSTLIncludePath()
const
7171 int TCling::DisplayClass(FILE* ,
const char* ,
int ,
int )
const
7180 int TCling::DisplayIncludePath(FILE *fout)
const
7182 assert(fout != 0 &&
"DisplayIncludePath, 'fout' parameter is null");
7184 llvm::SmallVector<std::string, 10> includePaths;
7186 fInterpreter->GetIncludePaths(includePaths,
false,
true);
7187 if (
const size_t nPaths = includePaths.size()) {
7188 assert(!(nPaths & 1) &&
"DisplayIncludePath, number of paths and options is not equal");
7190 std::string allIncludes(
"include path:");
7191 for (
size_t i = 0; i < nPaths; i += 2) {
7193 allIncludes += includePaths[i];
7195 if (includePaths[i] !=
"-I")
7197 allIncludes += includePaths[i + 1];
7200 fprintf(fout,
"%s\n", allIncludes.c_str());
7209 void* TCling::FindSym(
const char* entry)
const
7211 return fInterpreter->getAddressOfGlobal(entry);
7217 void TCling::GenericError(
const char* error)
const
7219 #if defined(R__MUST_REVISIT)
7220 #if R__MUST_REVISIT(6,2)
7221 Warning(
"GenericError",
"Interface not available yet.");
7239 Long_t TCling::GetExecByteCode()
const
7247 int TCling::GetSecurityError()
const
7249 #if defined(R__MUST_REVISIT)
7250 #if R__MUST_REVISIT(6,2)
7251 Warning(
"GetSecurityError",
"Interface not available yet.");
7260 int TCling::LoadFile(
const char* path)
const
7262 cling::Interpreter::CompilationResult compRes;
7263 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(
".L %s", path), compRes, 0);
7264 return compRes == cling::Interpreter::kFailure;
7273 Bool_t TCling::LoadText(
const char* text)
const
7275 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7281 const char* TCling::MapCppName(
const char* name)
const
7283 TTHREAD_TLS_DECL(std::string,buffer);
7284 ROOT::TMetaUtils::GetCppName(buffer,name);
7285 return buffer.c_str();
7294 void TCling::SetAlloclockfunc(
void (* )())
const
7304 void TCling::SetAllocunlockfunc(
void (* )())
const
7312 bool TCling::IsClassAutoloadingEnabled()
const
7314 if (IsFromRootCling())
7316 if (!fClingCallbacks)
7318 return fClingCallbacks->IsAutoloadingEnabled();
7325 int TCling::SetClassAutoloading(
int autoload)
const
7330 if ((
bool) autoload == IsClassAutoloadingEnabled())
7333 assert(fClingCallbacks &&
"We must have callbacks!");
7334 bool oldVal = fClingCallbacks->IsAutoloadingEnabled();
7335 fClingCallbacks->SetAutoloadingEnabled(autoload);
7343 int TCling::SetClassAutoparsing(
int autoparse)
7345 bool oldVal = fHeaderParsingOnDemand;
7346 fHeaderParsingOnDemand = autoparse;
7354 Bool_t TCling::SetSuspendAutoParsing(Bool_t value) {
7355 Bool_t old = fIsAutoParsingSuspended;
7356 fIsAutoParsingSuspended = value;
7357 if (fClingCallbacks) fClingCallbacks->SetAutoParsingSuspended(value);
7364 void TCling::SetErrmsgcallback(
void* p)
const
7366 #if defined(R__MUST_REVISIT)
7367 #if R__MUST_REVISIT(6,2)
7368 Warning(
"SetErrmsgcallback",
"Interface not available yet.");
7378 void TCling::SetTempLevel(
int val)
const
7384 int TCling::UnloadFile(
const char* path)
const
7386 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7387 std::string canonical = DLM->lookupLibrary(path);
7388 if (canonical.empty()) {
7392 cling::Interpreter::CompilationResult compRes;
7393 HandleInterpreterException(GetMetaProcessorImpl(), Form(
".U %s", canonical.c_str()), compRes, 0);
7394 return compRes == cling::Interpreter::kFailure;
7397 std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue()
const {
7398 return std::unique_ptr<TInterpreterValue>(
new TClingValue);
7404 void TCling::CodeComplete(
const std::string& line,
size_t& cursor,
7405 std::vector<std::string>& completions)
7407 fInterpreter->codeComplete(line, cursor, completions);
7412 int TCling::Evaluate(
const char* code, TInterpreterValue& value)
7414 auto V =
reinterpret_cast<cling::Value*
>(value.GetValAddr());
7415 auto compRes = fInterpreter->evaluate(code, *V);
7416 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7421 void TCling::RegisterTemporary(
const TInterpreterValue& value)
7423 using namespace cling;
7424 const Value* V =
reinterpret_cast<const Value*
>(value.GetValAddr());
7425 RegisterTemporary(*V);
7435 void TCling::RegisterTemporary(
const cling::Value& value)
7437 if (value.isValid() && value.needsManagedAllocation()) {
7438 R__LOCKGUARD(gInterpreterMutex);
7439 fTemporaries->push_back(value);
7448 TObject* TCling::GetObjectAddress(
const char *Name,
void *&LookupCtx)
7456 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7457 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7458 auto iSpecObj = iSpecObjMap->second.find(Name);
7459 if (iSpecObj != iSpecObjMap->second.end()) {
7460 LookupCtx = gDirectory;
7461 return iSpecObj->second;
7467 Sema &SemaR = fInterpreter->getSema();
7468 ASTContext& C = SemaR.getASTContext();
7469 Preprocessor &PP = SemaR.getPreprocessor();
7470 Parser& P =
const_cast<Parser&
>(fInterpreter->getParser());
7471 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7472 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7475 Token& Tok =
const_cast<Token&
>(P.getCurToken());
7476 Tok.setKind(tok::semi);
7482 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7485 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7488 Error(
"GetObjectAddress",
"Got a special object without LookupCtx!");
7490 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7501 void TCling::AddFriendToClass(clang::FunctionDecl*
function,
7502 clang::CXXRecordDecl* klass)
const
7504 using namespace clang;
7505 ASTContext& Ctx = klass->getASTContext();
7506 FriendDecl::FriendUnion friendUnion(
function);
7509 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7510 klass->pushFriendDecl(friendDecl);
7522 TInterpreter::DeclId_t TCling::GetDeclId(CallFunc_t* func)
const
7524 if (func)
return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7534 TInterpreter::DeclId_t TCling::GetDeclId(ClassInfo_t* cinfo)
const
7536 if (cinfo)
return ((TClingClassInfo*)cinfo)->GetDeclId();
7544 TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data)
const
7546 if (data)
return ((TClingDataMemberInfo*)data)->GetDeclId();
7554 TInterpreter::DeclId_t TCling::GetDeclId(MethodInfo_t* method)
const
7556 if (method)
return ((TClingMethodInfo*)method)->GetDeclId();
7564 TInterpreter::DeclId_t TCling::GetDeclId(TypedefInfo_t* tinfo)
const
7566 if (tinfo)
return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7577 void TCling::CallFunc_Delete(CallFunc_t* func)
const
7579 delete (TClingCallFunc*) func;
7584 void TCling::CallFunc_Exec(CallFunc_t* func,
void* address)
const
7586 TClingCallFunc* f = (TClingCallFunc*) func;
7592 void TCling::CallFunc_Exec(CallFunc_t* func,
void* address, TInterpreterValue& val)
const
7594 TClingCallFunc* f = (TClingCallFunc*) func;
7595 f->Exec(address, &val);
7600 void TCling::CallFunc_ExecWithReturn(CallFunc_t* func,
void* address,
void* ret)
const
7602 TClingCallFunc* f = (TClingCallFunc*) func;
7603 f->ExecWithReturn(address, ret);
7608 void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func,
void* address,
7609 const void* args[] ,
7613 TClingCallFunc* f = (TClingCallFunc*) func;
7614 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7619 Long_t TCling::CallFunc_ExecInt(CallFunc_t* func,
void* address)
const
7621 TClingCallFunc* f = (TClingCallFunc*) func;
7622 return f->ExecInt(address);
7627 Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func,
void* address)
const
7629 TClingCallFunc* f = (TClingCallFunc*) func;
7630 return f->ExecInt64(address);
7635 Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func,
void* address)
const
7637 TClingCallFunc* f = (TClingCallFunc*) func;
7638 return f->ExecDouble(address);
7643 CallFunc_t* TCling::CallFunc_Factory()
const
7645 R__LOCKGUARD(gInterpreterMutex);
7646 return (CallFunc_t*)
new TClingCallFunc(GetInterpreterImpl(), *fNormalizedCtxt);
7651 CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func)
const
7653 return (CallFunc_t*)
new TClingCallFunc(*(TClingCallFunc*)func);
7658 MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func)
const
7660 TClingCallFunc* f = (TClingCallFunc*) func;
7661 return (MethodInfo_t*) f->FactoryMethod();
7666 void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func,
bool ignore)
const
7668 TClingCallFunc* f = (TClingCallFunc*) func;
7669 f->IgnoreExtraArgs(ignore);
7674 void TCling::CallFunc_Init(CallFunc_t* func)
const
7676 R__LOCKGUARD(gInterpreterMutex);
7677 TClingCallFunc* f = (TClingCallFunc*) func;
7683 bool TCling::CallFunc_IsValid(CallFunc_t* func)
const
7685 TClingCallFunc* f = (TClingCallFunc*) func;
7686 return f->IsValid();
7691 TInterpreter::CallFuncIFacePtr_t
7692 TCling::CallFunc_IFacePtr(CallFunc_t * func)
const
7694 TClingCallFunc* f = (TClingCallFunc*) func;
7695 return f->IFacePtr();
7700 void TCling::CallFunc_ResetArg(CallFunc_t* func)
const
7702 TClingCallFunc* f = (TClingCallFunc*) func;
7708 void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param)
const
7710 TClingCallFunc* f = (TClingCallFunc*) func;
7716 void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param)
const
7718 TClingCallFunc* f = (TClingCallFunc*) func;
7724 void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param)
const
7726 TClingCallFunc* f = (TClingCallFunc*) func;
7732 void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param)
const
7734 TClingCallFunc* f = (TClingCallFunc*) func;
7740 void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param)
const
7742 TClingCallFunc* f = (TClingCallFunc*) func;
7748 void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param)
const
7750 TClingCallFunc* f = (TClingCallFunc*) func;
7756 void TCling::CallFunc_SetArgArray(CallFunc_t* func, Long_t* paramArr, Int_t nparam)
const
7758 TClingCallFunc* f = (TClingCallFunc*) func;
7759 f->SetArgArray(paramArr, nparam);
7764 void TCling::CallFunc_SetArgs(CallFunc_t* func,
const char* param)
const
7766 TClingCallFunc* f = (TClingCallFunc*) func;
7772 void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info,
const char* method,
const char* params, Long_t* offset)
const
7774 TClingCallFunc* f = (TClingCallFunc*) func;
7775 TClingClassInfo* ci = (TClingClassInfo*) info;
7776 f->SetFunc(ci, method, params, offset);
7781 void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info,
const char* method,
const char* params,
bool objectIsConst, Long_t* offset)
const
7783 TClingCallFunc* f = (TClingCallFunc*) func;
7784 TClingClassInfo* ci = (TClingClassInfo*) info;
7785 f->SetFunc(ci, method, params, objectIsConst, offset);
7789 void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info)
const
7791 TClingCallFunc* f = (TClingCallFunc*) func;
7792 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
7799 void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info,
const char* method,
const char* proto, Long_t* offset, EFunctionMatchMode mode )
const
7801 TClingCallFunc* f = (TClingCallFunc*) func;
7802 TClingClassInfo* ci = (TClingClassInfo*) info;
7803 f->SetFuncProto(ci, method, proto, offset, mode);
7809 void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info,
const char* method,
const char* proto,
bool objectIsConst, Long_t* offset, EFunctionMatchMode mode )
const
7811 TClingCallFunc* f = (TClingCallFunc*) func;
7812 TClingClassInfo* ci = (TClingClassInfo*) info;
7813 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
7819 void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info,
const char* method,
const std::vector<TypeInfo_t*> &proto, Long_t* offset, EFunctionMatchMode mode )
const
7821 TClingCallFunc* f = (TClingCallFunc*) func;
7822 TClingClassInfo* ci = (TClingClassInfo*) info;
7823 llvm::SmallVector<clang::QualType, 4> funcProto;
7824 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7825 iter != end; ++iter) {
7826 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7828 f->SetFuncProto(ci, method, funcProto, offset, mode);
7834 void 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 )
const
7836 TClingCallFunc* f = (TClingCallFunc*) func;
7837 TClingClassInfo* ci = (TClingClassInfo*) info;
7838 llvm::SmallVector<clang::QualType, 4> funcProto;
7839 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7840 iter != end; ++iter) {
7841 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7843 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
7846 std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func)
const
7848 TClingCallFunc *f = (TClingCallFunc *)func;
7849 std::string wrapper_name;
7850 std::string wrapper;
7851 f->get_wrapper_code(wrapper_name, wrapper);
7865 Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid)
const
7867 if (!declid)
return kFALSE;
7869 const clang::Decl *scope;
7870 if (info) scope = ((TClingClassInfo*)info)->GetDecl();
7871 else scope = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
7873 const clang::Decl *decl =
reinterpret_cast<const clang::Decl*
>(declid);
7874 const clang::DeclContext *ctxt = clang::Decl::castToDeclContext(scope);
7875 if (!decl || !ctxt)
return kFALSE;
7876 if (decl->getDeclContext()->Equals(ctxt))
7878 else if ((decl->getDeclContext()->isTransparentContext()
7879 || decl->getDeclContext()->isInlineNamespace())
7880 && decl->getDeclContext()->getParent()->Equals(ctxt))
7887 Long_t TCling::ClassInfo_ClassProperty(ClassInfo_t* cinfo)
const
7889 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7890 return TClinginfo->ClassProperty();
7895 void TCling::ClassInfo_Delete(ClassInfo_t* cinfo)
const
7897 delete (TClingClassInfo*) cinfo;
7902 void TCling::ClassInfo_Delete(ClassInfo_t* cinfo,
void* arena)
const
7904 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7905 TClinginfo->Delete(arena,*fNormalizedCtxt);
7910 void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo,
void* arena,
bool dtorOnly)
const
7912 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7913 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
7918 void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo,
void* arena)
const
7920 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7921 TClinginfo->Destruct(arena,*fNormalizedCtxt);
7926 ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all)
const
7928 R__LOCKGUARD(gInterpreterMutex);
7929 return (ClassInfo_t*)
new TClingClassInfo(GetInterpreterImpl(), all);
7934 ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo)
const
7936 return (ClassInfo_t*)
new TClingClassInfo(*(TClingClassInfo*)cinfo);
7941 ClassInfo_t* TCling::ClassInfo_Factory(
const char* name)
const
7943 R__LOCKGUARD(gInterpreterMutex);
7944 return (ClassInfo_t*)
new TClingClassInfo(GetInterpreterImpl(), name);
7947 ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid)
const
7949 R__LOCKGUARD(gInterpreterMutex);
7950 return (ClassInfo_t*)
new TClingClassInfo(GetInterpreterImpl(), (
const clang::Decl*)declid);
7956 int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo,
const char* method,
const char* proto, Bool_t objectIsConst , EFunctionMatchMode mode )
const
7958 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7959 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
7964 bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo)
const
7966 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7967 return TClinginfo->HasDefaultConstructor();
7972 bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo,
const char* name)
const
7974 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7975 return TClinginfo->HasMethod(name);
7980 void TCling::ClassInfo_Init(ClassInfo_t* cinfo,
const char* name)
const
7982 R__LOCKGUARD(gInterpreterMutex);
7983 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7984 TClinginfo->Init(name);
7989 void TCling::ClassInfo_Init(ClassInfo_t* cinfo,
int tagnum)
const
7991 R__LOCKGUARD(gInterpreterMutex);
7992 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7993 TClinginfo->Init(tagnum);
7998 bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo,
const char* name)
const
8000 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8001 return TClinginfo->IsBase(name);
8006 bool TCling::ClassInfo_IsEnum(
const char* name)
const
8008 return TClingClassInfo::IsEnum(GetInterpreterImpl(), name);
8013 Bool_t TCling::ClassInfo_IsScopedEnum(ClassInfo_t *info)
const
8015 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8016 return TClinginfo->IsScopedEnum();
8022 EDataType TCling::ClassInfo_GetUnderlyingType(ClassInfo_t* info)
const
8024 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8025 return TClinginfo->GetUnderlyingType();
8031 bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo)
const
8033 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8034 return TClinginfo->IsLoaded();
8039 bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo)
const
8041 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8042 return TClinginfo->IsValid();
8047 bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo,
const char* method,
const char* proto, Long_t* offset, EFunctionMatchMode mode )
const
8049 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8050 return TClinginfo->IsValidMethod(method, proto,
false, offset, mode);
8055 bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo,
const char* method,
const char* proto, Bool_t objectIsConst, Long_t* offset, EFunctionMatchMode mode )
const
8057 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8058 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8063 int TCling::ClassInfo_Next(ClassInfo_t* cinfo)
const
8065 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8066 return TClinginfo->Next();
8071 void* TCling::ClassInfo_New(ClassInfo_t* cinfo)
const
8073 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8074 return TClinginfo->New(*fNormalizedCtxt);
8079 void* TCling::ClassInfo_New(ClassInfo_t* cinfo,
int n)
const
8081 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8082 return TClinginfo->New(n,*fNormalizedCtxt);
8087 void* TCling::ClassInfo_New(ClassInfo_t* cinfo,
int n,
void* arena)
const
8089 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8090 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8095 void* TCling::ClassInfo_New(ClassInfo_t* cinfo,
void* arena)
const
8097 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8098 return TClinginfo->New(arena,*fNormalizedCtxt);
8103 Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo)
const
8105 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8106 return TClinginfo->Property();
8111 int TCling::ClassInfo_Size(ClassInfo_t* cinfo)
const
8113 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8114 return TClinginfo->Size();
8119 Long_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo)
const
8121 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8122 return TClinginfo->Tagnum();
8127 const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo)
const
8129 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8130 return TClinginfo->FileName();
8135 const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo)
const
8137 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8138 TTHREAD_TLS_DECL(std::string,output);
8139 TClinginfo->FullName(output,*fNormalizedCtxt);
8140 return output.c_str();
8145 const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo)
const
8147 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8148 return TClinginfo->Name();
8153 const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo)
const
8155 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8156 return TClinginfo->Title();
8161 const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo)
const
8163 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8164 return TClinginfo->TmpltName();
8176 void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo)
const
8178 delete(TClingBaseClassInfo*) bcinfo;
8183 BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo)
const
8185 R__LOCKGUARD(gInterpreterMutex);
8186 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8187 return (BaseClassInfo_t*)
new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8192 BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8193 ClassInfo_t* base)
const
8195 R__LOCKGUARD(gInterpreterMutex);
8196 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8197 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8198 return (BaseClassInfo_t*)
new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8203 int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo)
const
8205 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8206 return TClinginfo->Next();
8211 int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo,
int onlyDirect)
const
8213 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8214 return TClinginfo->Next(onlyDirect);
8219 Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo,
void * address,
bool isDerivedObject)
const
8221 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8222 return TClinginfo->Offset(address, isDerivedObject);
8227 Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase,
void * address,
bool isDerivedObject)
const
8229 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8230 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8232 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8235 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8240 Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo)
const
8242 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8243 return TClinginfo->Property();
8248 ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo)
const
8250 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8251 return (ClassInfo_t *)TClinginfo->GetBase();
8256 Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo)
const
8258 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8259 return TClinginfo->Tagnum();
8264 const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo)
const
8266 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8267 TTHREAD_TLS_DECL(std::string,output);
8268 TClinginfo->FullName(output,*fNormalizedCtxt);
8269 return output.c_str();
8274 const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo)
const
8276 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8277 return TClinginfo->Name();
8282 const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo)
const
8284 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8285 return TClinginfo->TmpltName();
8295 int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo)
const
8297 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8298 return TClinginfo->ArrayDim();
8303 void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo)
const
8305 delete(TClingDataMemberInfo*) dminfo;
8310 DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo )
const
8312 R__LOCKGUARD(gInterpreterMutex);
8313 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8314 return (DataMemberInfo_t*)
new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info);
8319 DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo)
const
8321 R__LOCKGUARD(gInterpreterMutex);
8322 const clang::Decl* decl =
reinterpret_cast<const clang::Decl*
>(declid);
8323 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8324 return (DataMemberInfo_t*)
new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8329 DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo)
const
8331 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8332 return (DataMemberInfo_t*)
new TClingDataMemberInfo(*TClinginfo);
8337 bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo)
const
8339 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8340 return TClinginfo->IsValid();
8345 int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim)
const
8347 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8348 return TClinginfo->MaxIndex(dim);
8353 int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo)
const
8355 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8356 return TClinginfo->Next();
8361 Long_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo)
const
8363 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8364 return TClinginfo->Offset();
8369 Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo)
const
8371 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8372 return TClinginfo->Property();
8377 Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo)
const
8379 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8380 return TClinginfo->TypeProperty();
8385 int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo)
const
8387 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8388 return TClinginfo->TypeSize();
8393 const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo)
const
8395 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8396 return TClinginfo->TypeName();
8401 const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo)
const
8403 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8404 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8409 const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo)
const
8411 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8412 return TClinginfo->Name();
8417 const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo)
const
8419 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8420 return TClinginfo->Title();
8425 const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo)
const
8427 TTHREAD_TLS_DECL(std::string,result);
8429 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8430 result = TClinginfo->ValidArrayIndex().str();
8431 return result.c_str();
8436 void TCling::SetDeclAttr(DeclId_t declId,
const char* attribute)
8438 Decl* decl =
static_cast<Decl*
>(
const_cast<void*
>(declId));
8439 ASTContext &C = decl->getASTContext();
8440 SourceRange commentRange;
8441 decl->addAttr(
new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8451 static void ConstructorName(std::string &name,
const clang::NamedDecl *decl,
8452 cling::Interpreter &interp,
8453 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8455 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8458 clang::QualType qualType(td->getTypeForDecl(),0);
8459 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8460 unsigned int level = 0;
8461 for(
size_t cursor = name.length()-1; cursor != 0; --cursor) {
8462 if (name[cursor] ==
'>') ++level;
8463 else if (name[cursor] ==
'<' && level) --level;
8464 else if (level == 0 && name[cursor] ==
':') {
8465 name.erase(0,cursor+1);
8473 void TCling::GetFunctionName(
const clang::FunctionDecl *decl, std::string &output)
const
8476 if (llvm::isa<clang::CXXConstructorDecl>(decl))
8478 ConstructorName(output, decl, *fInterpreter, *fNormalizedCtxt);
8480 }
else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8482 ConstructorName(output, decl, *fInterpreter, *fNormalizedCtxt);
8483 output.insert(output.begin(),
'~');
8485 llvm::raw_string_ostream stream(output);
8486 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8488 printPolicy.AnonymousTagLocations =
false;
8489 decl->getNameForDiagnostic(stream, printPolicy,
false);
8497 TInterpreter::DeclId_t TCling::GetDeclId(FuncTempInfo_t *info)
const
8499 return (DeclId_t)info;
8505 void TCling::FuncTempInfo_Delete(FuncTempInfo_t * )
const
8514 FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid)
const
8519 return (FuncTempInfo_t*)
const_cast<void*
>(declid);
8525 FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info)
const
8530 return (FuncTempInfo_t*)ft_info;
8536 Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info)
const
8548 UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info)
const
8550 if (!ft_info)
return 0;
8551 const clang::FunctionTemplateDecl *ft = (
const clang::FunctionTemplateDecl*)ft_info;
8552 return ft->getTemplateParameters()->size();
8559 UInt_t TCling::FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *ft_info)
const
8561 if (!ft_info)
return 0;
8562 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8563 return ft->getTemplateParameters()->getMinRequiredArguments();
8569 Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info)
const
8571 if (!ft_info)
return 0;
8574 property |= kIsCompiled;
8576 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8578 switch (ft->getAccess()) {
8579 case clang::AS_public:
8580 property |= kIsPublic;
8582 case clang::AS_protected:
8583 property |= kIsProtected;
8585 case clang::AS_private:
8586 property |= kIsPrivate;
8588 case clang::AS_none:
8589 if (ft->getDeclContext()->isNamespace())
8590 property |= kIsPublic;
8597 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8598 if (
const clang::CXXMethodDecl *md =
8599 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8600 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
8601 property |= kIsConstant | kIsConstMethod;
8603 if (md->isVirtual()) {
8604 property |= kIsVirtual;
8607 property |= kIsPureVirtual;
8609 if (
const clang::CXXConstructorDecl *cd =
8610 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8611 if (cd->isExplicit()) {
8612 property |= kIsExplicit;
8615 else if (
const clang::CXXConversionDecl *cd =
8616 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8617 if (cd->isExplicit()) {
8618 property |= kIsExplicit;
8629 Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info)
const
8631 if (!ft_info)
return 0;
8634 property |= kIsCompiled;
8636 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8637 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8639 if (fd->isOverloadedOperator())
8640 property |= kIsOperator;
8641 if (llvm::isa<clang::CXXConversionDecl>(fd))
8642 property |= kIsConversion;
8643 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8644 property |= kIsConstructor;
8645 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8646 property |= kIsDestructor;
8647 if (fd->isInlined())
8648 property |= kIsInlined;
8655 void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output)
const
8658 if (!ft_info)
return;
8659 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8661 GetFunctionName(ft->getTemplatedDecl(), buf);
8668 void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output)
const
8671 if (!ft_info)
return;
8672 const clang::FunctionTemplateDecl *ft = (
const clang::FunctionTemplateDecl*)ft_info;
8676 if (
const RedeclarableTemplateDecl *AnnotFD
8677 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((
const RedeclarableTemplateDecl*)ft)) {
8678 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8679 output = A->getAnnotation().str();
8683 if (!ft->isFromASTFile()) {
8687 output = ROOT::TMetaUtils::GetComment(*ft).str();
8700 void TCling::MethodInfo_Delete(MethodInfo_t* minfo)
const
8702 delete(TClingMethodInfo*) minfo;
8707 void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature)
const
8709 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8710 info->CreateSignature(signature);
8715 MethodInfo_t* TCling::MethodInfo_Factory()
const
8717 R__LOCKGUARD(gInterpreterMutex);
8718 return (MethodInfo_t*)
new TClingMethodInfo(GetInterpreterImpl());
8723 MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo)
const
8725 R__LOCKGUARD(gInterpreterMutex);
8726 return (MethodInfo_t*)
new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8731 MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid)
const
8733 const clang::Decl* decl =
reinterpret_cast<const clang::Decl*
>(declid);
8734 R__LOCKGUARD(gInterpreterMutex);
8735 const clang::FunctionDecl* fd = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl);
8736 return (MethodInfo_t*)
new TClingMethodInfo(GetInterpreterImpl(), fd);
8741 MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo)
const
8743 return (MethodInfo_t*)
new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8748 void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo)
const
8750 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8751 return info->InterfaceMethod(*fNormalizedCtxt);
8756 bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo)
const
8758 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8759 return info->IsValid();
8764 int TCling::MethodInfo_NArg(MethodInfo_t* minfo)
const
8766 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8767 return info->NArg();
8772 int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo)
const
8774 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8775 return info->NDefaultArg();
8780 int TCling::MethodInfo_Next(MethodInfo_t* minfo)
const
8782 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8783 return info->Next();
8788 Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo)
const
8790 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8791 return info->Property();
8796 Long_t TCling::MethodInfo_ExtraProperty(MethodInfo_t* minfo)
const
8798 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8799 return info->ExtraProperty();
8804 TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo)
const
8806 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8807 return (TypeInfo_t*)info->Type();
8812 const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo)
const
8814 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8815 TTHREAD_TLS_DECL(TString, mangled_name);
8816 mangled_name = info->GetMangledName();
8817 return mangled_name;
8822 const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo)
const
8824 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8825 return info->GetPrototype();
8830 const char* TCling::MethodInfo_Name(MethodInfo_t* minfo)
const
8832 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8833 return info->Name();
8838 const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo)
const
8840 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8841 return info->TypeName();
8846 std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo)
const
8848 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8849 if (info && info->IsValid())
8850 return info->Type()->NormalizedName(*fNormalizedCtxt);
8857 const char* TCling::MethodInfo_Title(MethodInfo_t* minfo)
const
8859 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8860 return info->Title();
8865 auto TCling::MethodCallReturnType(TFunction *func)
const -> EReturnType
8868 return MethodInfo_MethodCallReturnType(func->fInfo);
8870 return EReturnType::kOther;
8876 auto TCling::MethodInfo_MethodCallReturnType(MethodInfo_t* minfo)
const -> EReturnType
8878 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8879 if (info && info->IsValid()) {
8880 TClingTypeInfo *typeinfo = info->Type();
8881 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
8882 if (QT->isEnumeralType()) {
8883 return EReturnType::kLong;
8884 }
else if (QT->isPointerType()) {
8886 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
8887 if ( QT->isCharType() ) {
8888 return EReturnType::kString;
8890 return EReturnType::kOther;
8892 }
else if ( QT->isFloatingType() ) {
8893 int sz = typeinfo->Size();
8894 if (sz == 4 || sz == 8) {
8896 return EReturnType::kDouble;
8898 return EReturnType::kOther;
8900 }
else if ( QT->isIntegerType() ) {
8901 int sz = typeinfo->Size();
8910 return EReturnType::kLong;
8912 return EReturnType::kOther;
8915 return EReturnType::kOther;
8918 return EReturnType::kOther;
8929 void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo)
const
8931 delete(TClingMethodArgInfo*) marginfo;
8936 MethodArgInfo_t* TCling::MethodArgInfo_Factory()
const
8938 R__LOCKGUARD(gInterpreterMutex);
8939 return (MethodArgInfo_t*)
new TClingMethodArgInfo(GetInterpreterImpl());
8944 MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo)
const
8946 R__LOCKGUARD(gInterpreterMutex);
8947 return (MethodArgInfo_t*)
new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
8952 MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo)
const
8954 return (MethodArgInfo_t*)
8955 new TClingMethodArgInfo(*(TClingMethodArgInfo*)marginfo);
8960 bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo)
const
8962 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8963 return info->IsValid();
8968 int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo)
const
8970 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8971 return info->Next();
8976 Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo)
const
8978 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8979 return info->Property();
8984 const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo)
const
8986 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8987 return info->DefaultValue();
8992 const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo)
const
8994 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
8995 return info->Name();
9000 const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo)
const
9002 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9003 return info->TypeName();
9008 std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo)
const
9010 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9011 return info->Type()->NormalizedName(*fNormalizedCtxt);
9021 void TCling::TypeInfo_Delete(TypeInfo_t* tinfo)
const
9023 delete (TClingTypeInfo*) tinfo;
9028 TypeInfo_t* TCling::TypeInfo_Factory()
const
9030 R__LOCKGUARD(gInterpreterMutex);
9031 return (TypeInfo_t*)
new TClingTypeInfo(GetInterpreterImpl());
9036 TypeInfo_t* TCling::TypeInfo_Factory(
const char *name)
const
9038 R__LOCKGUARD(gInterpreterMutex);
9039 return (TypeInfo_t*)
new TClingTypeInfo(GetInterpreterImpl(), name);
9044 TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo)
const
9046 return (TypeInfo_t*)
new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9051 void TCling::TypeInfo_Init(TypeInfo_t* tinfo,
const char* name)
const
9053 R__LOCKGUARD(gInterpreterMutex);
9054 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9055 TClinginfo->Init(name);
9060 bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo)
const
9062 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9063 return TClinginfo->IsValid();
9068 const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo)
const
9070 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9071 return TClinginfo->Name();
9076 Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo)
const
9078 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9079 return TClinginfo->Property();
9084 int TCling::TypeInfo_RefType(TypeInfo_t* tinfo)
const
9086 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9087 return TClinginfo->RefType();
9092 int TCling::TypeInfo_Size(TypeInfo_t* tinfo)
const
9094 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9095 return TClinginfo->Size();
9100 const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo)
const
9102 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9103 return TClinginfo->TrueName(*fNormalizedCtxt);
9114 void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo)
const
9116 delete(TClingTypedefInfo*) tinfo;
9121 TypedefInfo_t* TCling::TypedefInfo_Factory()
const
9123 R__LOCKGUARD(gInterpreterMutex);
9124 return (TypedefInfo_t*)
new TClingTypedefInfo(GetInterpreterImpl());
9129 TypedefInfo_t* TCling::TypedefInfo_Factory(
const char *name)
const
9131 R__LOCKGUARD(gInterpreterMutex);
9132 return (TypedefInfo_t*)
new TClingTypedefInfo(GetInterpreterImpl(), name);
9137 TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo)
const
9139 return (TypedefInfo_t*)
new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9144 void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9145 const char* name)
const
9147 R__LOCKGUARD(gInterpreterMutex);
9148 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9149 TClinginfo->Init(name);
9154 bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo)
const
9156 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9157 return TClinginfo->IsValid();
9162 Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo)
const
9164 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9165 return TClinginfo->Next();
9170 Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo)
const
9172 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9173 return TClinginfo->Property();
9178 int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo)
const
9180 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9181 return TClinginfo->Size();
9186 const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo)
const
9188 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9189 return TClinginfo->TrueName(*fNormalizedCtxt);
9194 const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo)
const
9196 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9197 return TClinginfo->Name();
9202 const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo)
const
9204 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9205 return TClinginfo->Title();
9210 void TCling::SnapshotMutexState(ROOT::TVirtualRWMutex* mtx)
9212 if (!fInitialMutex.back()) {
9213 if (fInitialMutex.back().fRecurseCount) {
9214 Error(
"SnapshotMutexState",
"fRecurseCount != 0 even though initial mutex state is unset!");
9216 fInitialMutex.back().fState = mtx->GetStateBefore();
9220 ++fInitialMutex.back().fRecurseCount;
9225 void TCling::ForgetMutexState()
9227 if (!fInitialMutex.back())
9229 if (fInitialMutex.back().fRecurseCount == 0) {
9230 Error(
"ForgetMutexState",
"mutex state's recurse count already 0!");
9232 else if (--fInitialMutex.back().fRecurseCount == 0) {
9234 fInitialMutex.back().fState.reset();
9241 void TCling::ApplyToInterpreterMutex(
void *delta)
9243 R__ASSERT(!fInitialMutex.empty() &&
"Inconsistent state of fInitialMutex!");
9244 if (gInterpreterMutex) {
9246 auto typedDelta =
static_cast<TVirtualRWMutex::StateDelta *
>(delta);
9247 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP{typedDelta};
9248 gCoreMutex->Apply(std::move(uniqueP));
9251 fInitialMutex.pop_back();
9258 void *TCling::RewindInterpreterMutex()
9260 if (fInitialMutex.back()) {
9261 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP = gCoreMutex->Rewind(*fInitialMutex.back().fState);
9263 fInitialMutex.emplace_back();
9264 return uniqueP.release();
9267 fInitialMutex.emplace_back();