12#include "rootclingCommandLineOptionsHelp.h"
14#include "RConfigure.h"
34#include <unordered_map>
35#include <unordered_set>
47#define PATH_MAX _MAX_PATH
55#include <mach-o/dyld.h>
63#include <libprocstat.h>
72#include "cling/Interpreter/Interpreter.h"
73#include "cling/Interpreter/InterpreterCallbacks.h"
74#include "cling/Interpreter/LookupHelper.h"
75#include "cling/Interpreter/Value.h"
76#include "clang/AST/CXXInheritance.h"
77#include "clang/Basic/Diagnostic.h"
78#include "clang/Frontend/CompilerInstance.h"
79#include "clang/Frontend/FrontendActions.h"
80#include "clang/Frontend/FrontendDiagnostic.h"
81#include "clang/Lex/HeaderSearch.h"
82#include "clang/Lex/Preprocessor.h"
83#include "clang/Lex/ModuleMap.h"
84#include "clang/Lex/Pragma.h"
85#include "clang/Sema/Sema.h"
86#include "clang/Serialization/ASTWriter.h"
87#include "cling/Utils/AST.h"
89#include "llvm/ADT/StringRef.h"
91#include "llvm/Support/CommandLine.h"
92#include "llvm/Support/Path.h"
93#include "llvm/Support/PrettyStackTrace.h"
94#include "llvm/Support/Signals.h"
118#include <mach-o/dyld.h>
123#define strcasecmp _stricmp
124#define strncasecmp _strnicmp
132#define rootclingStringify(s) rootclingStringifyx(s)
133#define rootclingStringifyx(s) #s
140using std::string, std::map, std::ifstream, std::ofstream, std::endl, std::ios, std::vector;
162 gDriverConfig->fAddTypedefToROOTFile(
td->getQualifiedNameAsString().c_str());
170 if (clang::isa<clang::TranslationUnitDecl>(
en->getDeclContext())
171 || clang::isa<clang::LinkageSpecDecl>(
en->getDeclContext())
172 || clang::isa<clang::NamespaceDecl>(
en->getDeclContext()))
173 gDriverConfig->fAddEnumToROOTFile(
en->getQualifiedNameAsString().c_str());
187#if defined(__linux) || defined(__linux__)
196 if (
ret > 0 &&
ret < 1024) {
230 const cling::Interpreter &
interp)
248 clang::ASTContext &C =
decl.getASTContext();
254 if (! it->GetAttributeValue(propNames::name,
varName))
continue;
258 BaseSelectionRule::AttributesMap_t::iterator iter;
261 const std::string &
name = iter->first;
262 const std::string &
value = iter->second;
264 if (
name == propNames::name)
continue;
269 if (
name == propNames::iotype &&
270 (
decl.getType()->isArrayType() ||
decl.getType()->isPointerType())) {
271 const char *
msg =
"Data member \"%s\" is an array or a pointer. "
272 "It is not possible to assign to it the iotype \"%s\". "
273 "This transformation is possible only with data members "
274 "which are not pointers or arrays.\n";
284 if (
name == propNames::comment) {
285 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
value,
nullptr, 0));
289 if ((
name == propNames::transient &&
value ==
"true") ||
290 (
name == propNames::persistent &&
value ==
"false")) {
295 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
"!",
nullptr, 0));
321 using namespace clang;
323 llvm::StringRef comment;
340 BaseSelectionRule::AttributesMap_t::iterator iter;
343 const std::string &
name =
attr.first;
355 for (CXXRecordDecl::decl_iterator
I =
CXXRD.decls_begin(),
356 E =
CXXRD.decls_end();
I != E; ++
I) {
360 if (!(*I)->isImplicit()
372 if (comment.size()) {
375 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
382 (*I)->addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
406 while (
const clang::ConstantArrayType *
subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual())) {
410 return len.getLimitedValue();
416 const cling::Interpreter &
interp)
421 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
428 const cling::Interpreter &
interp)
468 size_t *end =
nullptr)
471 if (
line[0] !=
'#')
return false;
496 clang::Module *M =
recordDecl->getOwningModule()->getTopLevelModule();
514 if (classname.find(
':') == std::string::npos)
return;
517 int slen = classname.size();
518 for (
int k = 0; k <
slen; ++k) {
519 if (classname[k] ==
':') {
520 if (k + 1 >=
slen || classname[k + 1] !=
':') {
525 string base = classname.substr(0, k);
534 }
else if (classname[k] ==
'<') {
546 std::string classname;
548 while (file >>
line) {
550 if (
line.find(
"Library.") != 0)
continue;
552 int pos =
line.find(
":", 8);
553 classname =
line.substr(8, pos - 8);
559 while (
line[0] ==
' ')
line.replace(0, 1,
"");
563 if (classname ==
"ROOT::TImpProxy") {
582 const std::unordered_map<char, unsigned int>
keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
585 if (
line ==
"{ decls }") {
587 if (
line[0] ==
'[')
break;
594 while (
libs[0] ==
' ')
libs.replace(0, 1,
"");
618 if (llvm::sys::fs::is_directory(
filename))
continue;
626 file.seekg(0, std::ios::beg);
647 const string &fullname,
648 const clang::RecordDecl *cl,
649 cling::Interpreter &
interp)
652 const clang::FunctionDecl *
method
657 clang::TranslationUnitDecl *
TU =
658 cl->getASTContext().getTranslationUnitDecl();
663 if (
method !=
nullptr && (
method->getAccess() == clang::AS_public ||
method->getAccess() == clang::AS_none)) {
682 "in this version of ROOT, the option '!' used in a linkdef file\n"
683 " implies the actual existence of customized operators.\n"
684 " The following declaration is now required:\n"
699 int ncha = fullname.length() + 13;
724 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
735 "because it inherits from TObject but does not "
736 "have its own ClassDef.\n",
749 if (
m.getType().isConstQualified()) {
750 string ret =
"const_cast< ";
760 ret +=
m.getName().str();
764 return prefix +
m.getName().str();
774 const cling::Interpreter &
interp,
792 if (!
clxx ||
clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
794 const clang::ClassTemplateSpecializationDecl *
tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (
clxx);
802 const char *
tcl1 =
nullptr, *
tcl2 =
nullptr;
804 clang::QualType
ti =
arg0.getAsType();
822 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
828 if (
arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
832 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
834 }
else if (
m.getType()->isPointerType()) {
841 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
853 <<
" *" <<
stlName.c_str() <<
" = new " <<
stlType.c_str() <<
";" << std::endl
854 <<
" " <<
stlType.c_str() <<
" &R__stl = **" <<
stlName.c_str() <<
";" << std::endl;
858 <<
" " <<
stlName.c_str() <<
"[R__l] = new " <<
stlType.c_str() <<
";" << std::endl
859 <<
" " <<
stlType.c_str() <<
" &R__stl = *" <<
stlName.c_str() <<
"[R__l];" << std::endl;
863 dictStream <<
" R__stl.clear();" << std::endl;
866 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
867 <<
" if (R__tcl1==0) {" << std::endl
868 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
869 <<
fulName1.c_str() <<
"!\");" << std::endl
870 <<
" return;" << std::endl
871 <<
" }" << std::endl;
874 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
875 <<
" if (R__tcl2==0) {" << std::endl
876 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
877 <<
fulName2.c_str() <<
"!\");" << std::endl
878 <<
" return;" << std::endl
879 <<
" }" << std::endl;
883 <<
" R__b >> R__n;" << std::endl;
886 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
888 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
914 <<
" std::pair<Value_t const, " <<
tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
915 <<
" R__stl.insert(R__t3);" << std::endl;
923 dictStream <<
" R__stl.insert(R__t);" << std::endl;
928 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
931 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
937 <<
" }" << std::endl;
944 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
962 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
963 <<
" R__b << R__n;" << std::endl
964 <<
" if(R__n) {" << std::endl;
967 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
968 <<
" if (R__tcl1==0) {" << std::endl
969 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
970 <<
fulName1.c_str() <<
"!\");" << std::endl
971 <<
" return;" << std::endl
972 <<
" }" << std::endl;
975 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
976 <<
" if (R__tcl2==0) {" << std::endl
977 <<
" Error(\"" <<
stlName.c_str() <<
"streamer\",\"Missing the TClass object for " <<
fulName2.c_str() <<
"!\");" << std::endl
978 <<
" return;" << std::endl
979 <<
" }" << std::endl;
983 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
995 <<
" }" << std::endl;
1017 if (
m.getType()->isConstantArrayType()) {
1018 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1019 dictStream <<
"// Array of pointer to std::string are not supported (" <<
fieldname <<
"\n";
1022 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1025 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1026 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1027 fullIdx <<
"[R__i" << dim <<
"]";
1028 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1031 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1035 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1036 if (
m.getType()->isPointerType())
1038 <<
fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1044 if (
m.getType()->isPointerType())
1046 <<
fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1047 else if (
m.getType()->isConstantArrayType()) {
1049 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1052 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1053 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1054 fullIdx <<
"[R__i" << dim <<
"]";
1055 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1060 dictStream <<
" { TString R__str = " <<
fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1071 if (
m.getType()->isPointerType()) {
1072 if (
m.getType()->getPointeeType()->isPointerType()) {
1084 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1086 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1089 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1111 dictStream <<
"#include \"TInterpreter.h\"\n";
1113 dictStream <<
"//_______________________________________"
1114 <<
"_______________________________________" << std::endl;
1116 dictStream <<
"atomic_TClass_ptr " <<
clsname <<
"::fgIsA(nullptr); // static to hold class pointer" << std::endl
1119 <<
"//_______________________________________"
1120 <<
"_______________________________________" << std::endl;
1122 dictStream <<
"const char *" <<
clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1123 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1125 dictStream <<
"//_______________________________________"
1126 <<
"_______________________________________" << std::endl;
1128 dictStream <<
"const char *" <<
clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1129 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1130 <<
"*)nullptr)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1132 <<
"//_______________________________________"
1133 <<
"_______________________________________" << std::endl;
1135 dictStream <<
"int " <<
clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1136 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1137 <<
"*)nullptr)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1139 <<
"//_______________________________________"
1140 <<
"_______________________________________" << std::endl;
1142 dictStream <<
"TClass *" <<
clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1146 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1147 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1148 <<
"*)nullptr)->GetClass();" << std::endl
1149 <<
" return fgIsA;\n"
1150 <<
"}" << std::endl << std::endl
1152 <<
"//_______________________________________"
1153 <<
"_______________________________________" << std::endl;
1155 dictStream <<
"TClass *" <<
clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1159 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1160 dictStream << fullname <<
"*)nullptr)->GetClass(); }" << std::endl;
1163 <<
"}" << std::endl << std::endl;
1175 cling::Interpreter &
interp,
1178 if (cl->isAnonymousNamespace()) {
1190 if (classname !=
"ROOT") {
1194 dictStream <<
" namespace ROOTDict {" << std::endl;
1197 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1204 <<
" // Function generating the singleton type initializer" << std::endl
1207 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1208 <<
" {" << std::endl
1210 <<
" ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1211 <<
" {" << std::endl
1214 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1216 <<
" instance(\"" << classname.c_str() <<
"\", ";
1219 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1225 for (
unsigned int i = 0; i <
filename.length(); i++) {
1229 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1233 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1240 <<
" return &instance;" << std::endl
1241 <<
" }" << std::endl
1242 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1243 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1244 <<
" // Static variable to force the class initialization" << std::endl
1246 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1247 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1250 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1251 <<
" static TClass *" <<
mappedname.c_str() <<
"_Dictionary() {" << std::endl
1252 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1253 <<
" }" << std::endl << std::endl;
1272 llvm::StringRef
where;
1275 if (
index.size() == 0 && printError) {
1282 errorstring =
"has not been defined before the array";
1285 errorstring =
"is a private member of a parent class";
1294 if (
where.size() == 0) {
1296 member.getParent()->getName().str().c_str(),
member.getName().str().c_str());
1308 const cling::Interpreter &
interp,
1312 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1313 if (
clxx ==
nullptr)
return;
1326 dictStream <<
"//_______________________________________"
1327 <<
"_______________________________________" << std::endl;
1329 dictStream <<
"void " <<
clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1330 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1339 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1348 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1350 <<
" baseClass" <<
basestreamer <<
"::Streamer(R__b);" << std::endl;
1358 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1359 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1370 string classname = fullname;
1371 if (
strstr(fullname.c_str(),
"::")) {
1373 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1374 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1375 classname =
"thisClass";
1377 for (
int i = 0; i < 2; i++) {
1382 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1383 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1384 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1386 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1388 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1393 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1402 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1403 <<
" typedef " <<
base_fullname <<
" baseClass" << base <<
";" << std::endl
1404 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1413 for (clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
1419 std::string
type_name =
type.getAsString(
clxx->getASTContext().getPrintingPolicy());
1436 if (
strncmp(comment,
"!", 1)) {
1440 if (
type.getTypePtr()->isConstantArrayType() &&
1441 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1442 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1449 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1451 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: array of pointers to fundamental type (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1454 dictStream <<
" ;//R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1456 }
else if (
type.getTypePtr()->isPointerType()) {
1460 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1463 dictStream <<
" //R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1472 <<
"," <<
indexvar.str() <<
");" << std::endl;
1475 <<
"," <<
indexvar.str() <<
");" << std::endl;
1478 <<
"," <<
indexvar.str() <<
");" << std::endl;
1485 dictStream <<
" R__b.WriteFastArrayDouble32("
1493 }
else if (
type.getTypePtr()->isArrayType()) {
1495 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1497 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1501 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1504 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1507 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1512 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1515 dictStream <<
" R__b.ReadStaticArrayFloat16(" <<
field_iter->getName().str() <<
");" << std::endl;
1517 dictStream <<
" R__b.ReadStaticArrayDouble32(" <<
field_iter->getName().str() <<
");" << std::endl;
1520 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1525 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1528 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1531 << s <<
");" << std::endl;
1534 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1537 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1540 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1544 dictStream <<
" R__b.WriteArray((Int_t*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1546 dictStream <<
" R__b.WriteArrayFloat16(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1548 dictStream <<
" R__b.WriteArrayDouble32(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1550 dictStream <<
" R__b.WriteArray(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1557 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" <<
field_iter->getName().str() <<
");" << std::endl;
1564 <<
"=Float16_t(R_Dummy);}" << std::endl;
1570 <<
"=Double32_t(R_Dummy);}" << std::endl;
1592 if (
type.getTypePtr()->isConstantArrayType() &&
1593 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1594 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1601 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1612 }
else if (
type.getTypePtr()->isPointerType()) {
1620 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1647 }
else if (
const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1654 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1658 const char *
constwd =
"const ";
1663 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1667 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1674 <<
field_iter->getName().str() <<
"));" << std::endl;
1685 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1686 <<
" }" << std::endl
1687 <<
"}" << std::endl << std::endl;
1698 const cling::Interpreter &
interp,
1704 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1705 if (
clxx ==
nullptr)
return;
1710 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1728 dictStream <<
"//_______________________________________"
1729 <<
"_______________________________________" << std::endl;
1733 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1734 <<
" if (R__b.IsReading()) {" << std::endl
1735 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1736 <<
" } else {" << std::endl
1737 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1738 <<
" }" << std::endl
1739 <<
"}" << std::endl << std::endl;
1750 const cling::Interpreter &
interp,
1772 for (std::string& arg : InputFiles) {
1775 for (
int j = 0;
j < 3;
j++) {
1776 if (arg[
l] ==
'-') {
1781 if (arg[
l] ==
'!') {
1786 if (arg[
l] ==
'+') {
1802 llvm::SmallString<256>
filestem = llvm::sys::path::filename(arg);
1803 llvm::sys::path::replace_extension(
filestem,
"");
1842 for (
size_t i = 0; i <
nPaths; i += 1 ) {
1891 cling::Interpreter &
interp,
1894 std::ostringstream out;
1898 modGen.WriteUmbrellaHeader(out);
1899 if (
interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1907 modGen.WriteContentHeader(out);
1920 clang::Module *
module =
nullptr)
1923 llvm::SmallVector<char, 128> buffer;
1924 llvm::BitstreamWriter stream(buffer);
1926 std::unique_ptr<llvm::raw_ostream> out =
1941 out->write(&buffer.front(), buffer.size());
1955 assert(
modGen.IsPCH() &&
"modGen must be in PCH mode");
1957 std::string
iSysRoot(
"/DUMMY_SYSROOT/include/");
1973 for (
const std::string &header :
headers) {
1974 includes <<
"#include \"" << header <<
"\"\n";
1978 return result == cling::Interpreter::CompilationResult::kSuccess;
1987#ifdef __INTEL_COMPILER
2000#ifdef __GNUC_MINOR__
2016#ifdef _STLPORT_VERSION
2055#if defined(_WIN64) && defined(_DEBUG)
2067 return llvm::sys::path::filename(path).str();
2077 if (std::string::npos != pos) {
2078 dirname.assign(path.begin(), path.begin() + pos + 1);
2146 const cling::Interpreter &
interp)
2148 if (!
decls.empty()) {
2155 names.push_back(
d->getQualifiedNameAsString());
2176 const std::list<std::string> &
nsNames,
2177 const std::list<std::string> &
tdNames,
2178 const std::list<std::string> &
enNames,
2179 const std::list<std::string> &
varNames,
2213 rootmapFile <<
"class " << className << std::endl;
2220 if (className.find(
"<") != std::string::npos)
continue;
2224 auto &header =
headers.front();
2245 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2254 rootmapFile <<
"# List of selected enums and outer classes\n";
2281 if (
foundNsPos == std::string::npos)
return {
"",
""};
2337 std::list<std::string> &
el_list,
2338 std::unordered_set<std::string> &
el_set)
2345 if (
el_set.insert(tmp).second && !tmp.empty()) {
2396 std::cerr <<
"FATAL: A class with normalized name " <<
normalizedName
2397 <<
" was already selected. This means that two different instances of"
2398 <<
" clang::RecordDecl had the same name, which is not possible."
2399 <<
" This can be a hint of a serious problem in the class selection."
2400 <<
" In addition, the generated dictionary would not even compile.\n";
2414 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl)) {
2456 !llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl) &&
2510 if (clang::CXXRecordDecl *
CXXRD =
2511 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2523 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2526 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2529 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2545 if (
interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2546 "#include \"TFile.h\"\n"
2547 "#include \"TObjArray.h\"\n"
2548 "#include \"TVirtualArray.h\"\n"
2549 "#include \"TStreamerElement.h\"\n"
2550 "#include \"TProtoClass.h\"\n"
2551 "#include \"TBaseClass.h\"\n"
2552 "#include \"TListOfDataMembers.h\"\n"
2553 "#include \"TListOfEnums.h\"\n"
2554 "#include \"TListOfEnumsWithLock.h\"\n"
2555 "#include \"TDataMember.h\"\n"
2556 "#include \"TEnum.h\"\n"
2557 "#include \"TEnumConstant.h\"\n"
2558 "#include \"TDictAttributeMap.h\"\n"
2559 "#include \"TMessageHandler.h\"\n"
2560 "#include \"TArray.h\"\n"
2561 "#include \"TRefArray.h\"\n"
2562 "#include \"root_std_complex.h\"\n")
2563 != cling::Interpreter::kSuccess)
2599 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2600 if (
nsName.find(
"(anonymous)") == std::string::npos)
2605 if (!
selClass.GetRecordDecl()->isCompleteDefinition()) {
2609 if (
selClass.RequestOnlyTClass()) {
2617 if (clang::CXXRecordDecl *
CXXRD =
2618 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2622 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2630 }
else if (
CRD->getName() ==
"RVec") {
2631 static const clang::DeclContext *
vecOpsDC =
nullptr;
2633 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2634 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2656 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2660 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2672 if (!
selClass.GetRecordDecl()->isCompleteDefinition() || !
selClass.RequestOnlyTClass()) {
2676 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2722 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2723 <<
"#define R__DICTIONARY_FILENAME " <<
main_dictname << std::endl
2726 <<
"#define R__NO_DEPRECATION" << std::endl
2731 <<
"\n/*******************************************************************/\n"
2732 <<
"#include <cstddef>\n"
2733 <<
"#include <cstdio>\n"
2734 <<
"#include <cstdlib>\n"
2735 <<
"#include <cstring>\n"
2736 <<
"#include <cassert>\n"
2737 <<
"#define G__DICTIONARY\n"
2738 <<
"#include \"ROOT/RConfig.hxx\"\n"
2739 <<
"#include \"TClass.h\"\n"
2740 <<
"#include \"TDictAttributeMap.h\"\n"
2741 <<
"#include \"TInterpreter.h\"\n"
2742 <<
"#include \"TROOT.h\"\n"
2743 <<
"#include \"TBuffer.h\"\n"
2744 <<
"#include \"TMemberInspector.h\"\n"
2745 <<
"#include \"TInterpreter.h\"\n"
2746 <<
"#include \"TVirtualMutex.h\"\n"
2747 <<
"#include \"TError.h\"\n\n"
2748 <<
"#ifndef G__ROOT\n"
2749 <<
"#define G__ROOT\n"
2751 <<
"#include \"RtypesImp.h\"\n"
2752 <<
"#include \"TIsAProxy.h\"\n"
2753 <<
"#include \"TFileMergeInfo.h\"\n"
2754 <<
"#include <algorithm>\n"
2755 <<
"#include \"TCollectionProxyInfo.h\"\n"
2756 <<
"/*******************************************************************/\n\n"
2757 <<
"#include \"TDataMember.h\"\n\n";
2764 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2765 <<
"namespace std {} using namespace std;\n\n";
2774 dictStream <<
"// Header files passed as explicit arguments\n"
2776 <<
"// Header files passed via #pragma extra_include\n"
2783#if defined(R__IOSSIM) || defined(R__IOS)
2844 for (
unsigned int i = 0; i <
m_size; ++i) {
2852 if (
ifile.is_open())
2854 if (0 != std::remove(
tmpName)) {
2867 for (
unsigned int i = 0; i <
m_size; ++i) {
2876 if (
ifile.is_open())
2884 llvm::sys::fs::remove(
tmpName);
2909 std::cout <<
"Restoring files in temporary file catalog:\n";
2910 for (
unsigned int i = 0; i <
m_size; ++i) {
2943 static const std::string pattern(
"-Wno-");
2945 if (arg.find(pattern) != 0)
2956 cling::Interpreter &
interp)
2981 if (
qt.isNull())
return qt;
2983 while (
thisQt->isPointerType() ||
2984 thisQt->isReferenceType()) {
2995 const cling::Interpreter &
interp,
2998 std::list<std::string>
headers;
3001 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
3008 if (
const clang::ClassTemplateSpecializationDecl *
tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&
rcd)) {
3011 for (
auto &
tArg :
tsd->getTemplateArgs().asArray()) {
3012 if (clang::TemplateArgument::ArgKind::Type !=
tArg.getKind())
continue;
3033 if (
const clang::FieldDecl *
fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*
declIt)) {
3046 for (
auto & fPar :
methodIt->parameters()) {
3081 if (!
dclCtxt->isStdNamespace()){
3101 if (
argKind != clang::TemplateArgument::Type){
3102 if (
argKind == clang::TemplateArgument::Integral)
continue;
3109 if (
isPOD)
continue;
3134 const cling::Interpreter &
interp)
3137 std::unordered_set<std::string> buffer;
3142 if (
const clang::CXXRecordDecl *
cxxRcd =
3143 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
annotatedRcd.GetRecordDecl())) {
3149 headers.remove_if([&buffer](
const std::string & s) {
3150 return !buffer.insert(s).second;
3163 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(
cxxRcd)){
3172 if (clang::CXXRecordDecl *
cxxRcd =
tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3179 headers.remove_if([&buffer](
const std::string & s) {
3180 return !buffer.insert(s).second;
3211 const cling::Interpreter &
interp)
3219 std::unordered_set<std::string>
fwdDecls;
3262 std::cout <<
"Logs from forward decl printer: \n"
3293 std::cout <<
"Class-headers Mapping:\n";
3309 std::cout << std::endl;
3336 static const std::vector<std::string>
namePrfxes {
3341 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3359 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3373 std::cerr <<
"Error: Class " <<
clName <<
" has been selected but "
3374 <<
"currently the support for its I/O is not yet available. Note that "
3375 <<
clName <<
", even if not selected, will be available for "
3376 <<
"interpreted code.\n";
3380 std::cerr <<
"Error: It is not necessary to explicitly select class "
3381 <<
clName <<
". I/O is supported for it transparently.\n";
3396 InterpreterCallbacks(
interp),
3402 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3403 clang::OptionalFileEntryRef , llvm::StringRef ,
3404 llvm::StringRef ,
const clang::Module * ,
bool ,
3405 clang::SrcMgr::CharacteristicKind )
override
3440 using namespace clang;
3441 if (llvm::StringRef(M->Name).ends_with(
"ACLiC_dict")) {
3447 assert(M &&
"Must have module Core");
3454 llvm::cl::desc(
"Allow implicit build of system modules."),
3456static llvm::cl::list<std::string>
3459 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3462static llvm::cl::opt<std::string>
3464 llvm::cl::desc(
"<output dictionary file>"),
3496 using namespace clang::diag;
3503 const clang::Module *
module = nullptr;
3506 const auto &ID =
Info.getID();
3509 module = fMap.findModule(moduleName);
3515 "Couldn't find module %s in the available modulemaps. This"
3516 "prevents us from correctly diagnosing wrongly built modules.\n",
3547 "Building module '%s' implicitly. If '%s' requires a \n"
3548 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3549 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3559 DiagnosticConsumer::clear();
3565 DiagnosticConsumer::BeginSourceFile(
LangOpts,
PP);
3571 DiagnosticConsumer::EndSourceFile();
3577 DiagnosticConsumer::finish();
3584#if defined(_WIN32) && defined(_MSC_VER)
3588 const char *
EnablePopups = std::getenv(
"Cling_GuiOnAssert");
3601static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3603static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3614static llvm::cl::opt<VerboseLevel>
3616 llvm::cl::values(
clEnumVal(
v,
"Show errors."),
3625static llvm::cl::opt<bool>
3626gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3629static llvm::cl::opt<bool>
3630gOptReflex(
"reflex", llvm::cl::desc(
"Behave internally like genreflex."),
3632static llvm::cl::opt<bool>
3633gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3636static llvm::cl::opt<std::string>
3638 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3641static llvm::cl::opt<bool>
3643 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3646static llvm::cl::opt<bool>
3647gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3649static llvm::cl::opt<bool>
3650gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3652static llvm::cl::list<std::string>
3654 llvm::cl::desc(
"Generate rootmap file."),
3656static llvm::cl::opt<std::string>
3658 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3660static llvm::cl::opt<bool>
3662 llvm::cl::desc(
"Generate a C++ module."),
3664static llvm::cl::list<std::string>
3666 llvm::cl::desc(
"Specify a C++ modulemap file."),
3669static llvm::cl::opt<bool>
3671 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3673static llvm::cl::opt<bool>
3675 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3677static llvm::cl::opt<bool>
3679 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3681static llvm::cl::opt<bool>
3683 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3685static llvm::cl::opt<bool>
3687 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3688information and another the interactivity support."),
3690static llvm::cl::opt<bool>
3693 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3695static llvm::cl::opt<std::string>
3697 llvm::cl::desc(
"The path to the library of the built dictionary."),
3699static llvm::cl::list<std::string>
3701 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3703static llvm::cl::list<std::string>
3705 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3709static llvm::cl::opt<bool>
3711 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3719static llvm::cl::opt<bool>
3722 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3724static llvm::cl::opt<bool>
3726 llvm::cl::desc(
"Check the selection syntax only."),
3728static llvm::cl::opt<bool>
3730 llvm::cl::desc(
"Fail if there are warnings."),
3732static llvm::cl::opt<bool>
3734 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3736static llvm::cl::opt<std::string>
3738 llvm::cl::desc(
"Specify an isysroot."),
3740 llvm::cl::init(
"-"));
3741static llvm::cl::list<std::string>
3743 llvm::cl::desc(
"Specify an include path."),
3745static llvm::cl::list<std::string>
3747 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3749static llvm::cl::list<std::string>
3751 llvm::cl::desc(
"Specify a system include path."),
3753static llvm::cl::list<std::string>
3755 llvm::cl::desc(
"Specify defined macros."),
3757static llvm::cl::list<std::string>
3759 llvm::cl::desc(
"Specify undefined macros."),
3761static llvm::cl::list<std::string>
3763 llvm::cl::desc(
"Specify compiler diagnostics options."),
3766static llvm::cl::list<std::string>
3768 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file | selection xml file>"),
3770static llvm::cl::list<std::string>
3772 llvm::cl::desc(
"Consumes all unrecognized options."),
3775static llvm::cl::SubCommand
3778static llvm::cl::list<std::string>
3780 llvm::cl::desc(
"Consumes options and sends them to cling."),
3809 for (
const std::string &header :
modGen.GetHeaders()) {
3814 clang::ConstSearchDirIterator *
CurDir =
nullptr;
3816 header, clang::SourceLocation(),
3819 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>>(),
3858 clang::HeaderSearch &
headerSearch =
CI->getPreprocessor().getHeaderSearchInfo();
3862 clang::Module *
module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3878 msgStream <<
"after creating module \"" <<
module->Name << "\" ";
3879 if (!
module->PresumedModuleMapFile.empty())
3880 msgStream <<
"using modulemap \"" <<
module->PresumedModuleMapFile << "\" ";
3881 msgStream <<
"the following headers are not part of that module:\n";
3885 msgStream <<
" (already part of module \"" <<
H[1] <<
"\")";
3901 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3911 [](
const std::array<std::string, 2>&
HdrMod) { return HdrMod[0];});
3949 llvm::PrettyStackTraceProgram
X(
argc,
argv);
3952#if defined(R__WIN32) && !defined(R__WINGCC)
3973 auto &
opts = llvm::cl::getRegisteredOptions();
3976 llvm::cl::desc(
"Alias for -help"),
3977 llvm::cl::aliasopt(*
optHelp));
3979 llvm::cl::desc(
"Alias for -help"),
3980 llvm::cl::aliasopt(*
optHelp));
3982 llvm::cl::ParseCommandLineOptions(
argc,
argv,
"rootcling");
4007 return interp->getDiagnostics().hasFatalErrorOccurred();
4024 llvm::cl::PrintHelpMessage();
4039 if ((fp =
fopen(
filein.c_str(),
"r")) ==
nullptr) {
4067 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4068 llvm::cl::PrintHelpMessage();
4080 std::list<std::string>
diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4086 if (GetErrorIgnoreLevel() >
kWarning)
4088 GetWarningsAreErrors() =
true;
4102 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4138 std::vector<std::string>
pcmArgs;
4152 [&](
const std::string& path){
4153 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4161 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(
etcDir));
4168 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4169#elif defined(R__WIN32)
4170 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4177 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4185 clingArgs.push_back(
"-fmodules-embed-all-files");
4249 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4250 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4251 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4252 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4254 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4255 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4259 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4261 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4263 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4264 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4265 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4266 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4267 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4268 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4269 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4271 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4286 std::cerr <<
"Argument \""<<
clingArg <<
"\" is not a supported cling argument. "
4287 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4295 cling::Interpreter*
interpPtr =
nullptr;
4323 clang::CompilerInstance *
CI =
interp.getCI();
4325 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4326 CI->getSourceManager().setAllFilesAreTransient(
true);
4328 clang::Preprocessor &
PP =
CI->getPreprocessor();
4338 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4349 interp.DumpIncludePath();
4354 interp.printIncludedFiles(llvm::outs());
4355 llvm::outs() <<
"\n\n";
4356 llvm::outs().flush();
4360 =
interp.getCI()->getASTContext().getLangOpts();
4361#define LANGOPT(Name, Bits, Default, Description) \
4362 ROOT::TMetaUtils::Info(nullptr, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4363#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4364#include "clang/Basic/LangOptions.def"
4368 interp.getOptions().ErrorOut =
true;
4369 interp.enableRawInput(
true);
4373 if (
DepMod.ends_with(
"_rdict.pcm")) {
4380 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4390 if (
interp.declare(
"#include <cassert>\n"
4391 "#include \"Rtypes.h\"\n"
4392 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4400 if (
interp.declare(
"#include <string>\n"
4401 "#include <RtypesCore.h>\n"
4402 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4498 std::stringstream res;
4499 const char*
delim=
"\n";
4502 std::ostream_iterator<std::string>(res,
delim));
4503 if (
interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4512 clang::PragmaNamespace(
pragma) {}
4513 void HandlePragma(clang::Preprocessor &
PP,
4515 clang::Token &
tok)
override {
4516 PP.DiscardUntilEndOfDirective();
4600 if (
dh != std::string::npos) {
4664 if (file.is_open()) {
4696 if (file.is_open()) {
4737 <<
"#include \"TVirtualObject.h\"\n"
4738 <<
"#include <vector>\n"
4739 <<
"#include \"TSchemaHelper.h\"\n\n";
4779 scan.
Scan(
CI->getASTContext());
4802 if (
annRcd.RequestNoInputOperator()) {
4965 [](
const std::string &
a,
const std::string &
b) -> std::string {
4966 if (a.empty()) return b;
4967 else return a +
" " + b;
4997 std::list<std::string>
nsNames;
5040 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
5041 CI->getSema().getASTConsumer().HandleTranslationUnit(
CI->getSema().getASTContext());
5077 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5091 for (
int i = 1; i <
argc; ++i) {
5094 args.push_back(
argv[i]);
5104 std::cout <<
"Args: \n";
5105 for (std::vector<std::string>::iterator it = args.begin();
5106 it < args.end(); ++it) {
5107 std::cout << i <<
") " << *it << std::endl;
5121 if (std::string::npos !=
result) {
5133 const unsigned int size(str.size());
5134 char *
a =
new char[
size + 1];
5168 const std::string &
optName =
"")
5180 const std::string &
optName =
"")
5197 const std::vector<std::string> &
pcmsNames,
5198 const std::vector<std::string> &
includes,
5201 const std::vector<std::string> &
warnings,
5239 "*** genreflex: No rootmap lib and several header specified!\n");
5332 for (
int i = 0; i <
argc; i++) {
5338 std::cout <<
cmd << std::endl;
5347 for (
int i = 0; i <
argc; i++)
5362 const std::vector<std::string> &
pcmsNames,
5363 const std::vector<std::string> &
includes,
5366 const std::vector<std::string> &
warnings,
5391 for (
unsigned int i = 0; i <
headersNames.size(); ++i) {
5433 std::vector<std::string> &values)
5438 values.reserve(
nVals);
5443 << opt->arg << std::endl;
5445 values.push_back(opt->arg);
5460 "*** genereflex: %s is not supported anymore.\n",
5553 "********************************************************************************\n"
5554 "* The genreflex utility does not allow to generate C++ modules containing *\n"
5555 "* reflection information required at runtime. Please use rootcling instead *\n"
5556 "* To print the rootcling invocation that corresponds to the current genreflex *\n"
5557 "* invocation please use the --print-rootcling-invocation flag. *\n"
5558 "********************************************************************************\n"
5560 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5561 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5565 "--print-rootcling-invocation\n"
5566 " Print to screen the rootcling invocation corresponding to the current \n"
5567 " genreflex invocation.\n";
5570 "-s, --selection_file\tSelection filename\n"
5571 " Class selection file to specify for which classes the dictionary\n"
5572 " will be generated. The final set can be crafted with exclusion and\n"
5573 " exclusion rules.\n"
5574 " Properties can be specified. Some have special meaning:\n"
5575 " - name [string] name of the entity to select with an exact matching\n"
5576 " - pattern [string] name with wildcards (*) to select entities\n"
5577 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5578 " file where the C++ entities reside and not to C++ entities themselves.\n"
5579 " - transient/persistent [string: true/false] The fields to which they are\n"
5580 " applied will not be persistified if requested.\n"
5581 " - comment [string]: what you could write in code after an inline comment\n"
5582 " without \"//\". For example comment=\"!\" or \"||\".\n"
5583 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5584 " Default value is 'false'\n"
5585 " - rntupleStreamerMode [true/false]: enforce streamed or native writing for RNTuple.\n"
5586 " If unset, RNTuple stores classes in split mode or fails if the class cannot be split.\n"
5587 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5588 " to 'true'. Default value is 'false'\n"
5592 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5593 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5594 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5595 " [noInputOperator=\"true/false\"]\n"
5596 " [rntupleStreamerMode=\"true/false\"] />\n"
5597 " <class name=\"classname\" >\n"
5598 " <field name=\"m_transient\" transient=\"true\"/>\n"
5599 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5600 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5601 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5603 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5604 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5605 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5608 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5609 " <method name=\"unwanted\" />\n"
5614 " If no selection file is specified, the class with the filename without\n"
5615 " extension will be selected, i.e. myClass.h as argument without any\n"
5616 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5619 "-o, --output\tOutput filename\n"
5620 " Output file name. If an existing directory is specified instead of a file,\n"
5621 " then a filename will be built using the name of the input file and will\n"
5622 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5623 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5624 " have unique names.\n";
5628 "-l, --library\tTarget library\n"
5629 " The flag -l must be followed by the name of the library that will\n"
5630 " contain the object file corresponding to the dictionary produced by\n"
5631 " this invocation of genreflex.\n"
5632 " The name takes priority over the one specified for the rootmapfile.\n"
5633 " The name influences the name of the created pcm:\n"
5634 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5635 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5636 " Any \"liblib\" occurrence is transformed in the expected \"lib\".\n"
5637 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5638 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5641 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5642 " This file lists the autoload keys. For example classes for which the\n"
5643 " reflection information is provided.\n"
5644 " The format of the rootmap is the following:\n"
5645 " - Forward declarations section\n"
5646 " - Libraries sections\n"
5647 " Rootmaps can be concatenated together, for example with the cat util.\n"
5648 " In order for ROOT to pick up the information in the rootmaps, they\n"
5649 " have to be located in the library path and have the .rootmap extension.\n"
5650 " An example rootmap file could be:\n"
5652 " template <class T> class A;\n"
5653 " [ libMyLib.so ]\n"
5654 " class A<double>\n"
5660 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5676 "",
"print-rootcling-invocation",
5702 "--multiDict\tSupport for many dictionaries in one library\n"
5703 " Form correct pcm names if multiple dictionaries will be in the same\n"
5704 " library (needs target library switch. See its documentation).\n"
5711 "" ,
"noGlobalUsingStd" ,
5713 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5714 " All header files must have sumbols from std:: namespace fully qualified\n"
5720 "s" ,
"selection_file" ,
5736 "" ,
"rootmap-lib" ,
5744 "" ,
"interpreteronly",
5746 "--interpreteronly\tDo not generate I/O related information.\n"
5747 " Generate minimal dictionary required for interactivity.\n"
5755 "--split\tSplit the dictionary\n"
5756 " Split in two the dictionary, isolating the part with\n"
5757 " ClassDef related functions in a separate file.\n"
5765 "-m \tPcm file loaded before any header (option can be repeated).\n"
5773 "-v, --verbose\tPrint some debug information.\n"
5781 "--debug\tPrint all debug information.\n"
5789 "--quiet\tPrint only warnings and errors (default).\n"
5797 "--silent\tPrint no information at all.\n"
5803 "" ,
"writeEmptyPCM",
5805 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5813 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5822 "--help\tPrint usage and exit.\n"
5828 "",
"fail_on_warnings",
5830 "--fail_on_warnings\tFail on warnings and errors.\n"
5836 "",
"selSyntaxOnly",
5838 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5844 "" ,
"noIncludePaths",
5846 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5885 "" ,
"no_membertypedefs" ,
5893 "" ,
"no_templatetypedefs" ,
5898 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
5912 std::vector<ROOT::option::Option> options(stats.
options_max);
5913 std::vector<ROOT::option::Option> buffer(stats.
buffer_max);
5919 if (parse.
error()) {
5955 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
5980 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6000 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6152 if (std::string::npos !=
exeName.find(
"genreflex"))
6160 ROOT::TMetaUtils::Info(
nullptr,
"Problems have been detected during the generation of the dictionary.\n");
Select classes and assign properties using C++ syntax.
The file contains utilities which are foundational and could be used across the core component of ROO...
This is the only file required to use The Lean Mean C++ Option Parser.
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Basic types used by ROOT and required by TInterpreter.
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
std::unordered_map< std::string, std::string > AttributesMap_t
Custom diag client for clang that verifies that each implicitly build module is a system module.
void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override
~CheckModuleBuildClient() override
CheckModuleBuildClient(clang::DiagnosticConsumer *Child, bool OwnsChild, clang::ModuleMap &Map)
clang::DiagnosticConsumer * fChild
bool IncludeInDiagnosticCounts() const override
void EndSourceFile() override
void BeginSourceFile(const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) override
const_iterator begin() const
const_iterator end() const
A parsed option from the command line together with its argument if it has one.
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
bool error()
Returns true if an unrecoverable error occurred while parsing options.
void Scan(const clang::ASTContext &C)
std::vector< ROOT::TMetaUtils::AnnotatedRecordDecl > ClassColl_t
const DeclsSelRulesMap_t & GetDeclsSelRulesMap() const
FunctionColl_t fSelectedFunctions
std::vector< const clang::FunctionDecl * > FunctionColl_t
NamespaceColl_t fSelectedNamespaces
TypedefColl_t fSelectedTypedefs
DeclCallback SetRecordDeclCallback(DeclCallback callback)
Set the callback to the RecordDecl and return the previous one.
std::map< const clang::Decl *, const BaseSelectionRule * > DeclsSelRulesMap_t
EnumColl_t fSelectedEnums
std::vector< const clang::TypedefNameDecl * > TypedefColl_t
std::vector< const clang::VarDecl * > VariableColl_t
static bool GetDeclQualName(const clang::Decl *D, std::string &qual_name)
VariableColl_t fSelectedVariables
std::vector< const clang::EnumDecl * > EnumColl_t
ClassColl_t fSelectedClasses
The class representing the collection of selection rules.
~TRootClingCallbacks() override
void InclusionDirective(clang::SourceLocation, const clang::Token &, llvm::StringRef FileName, bool IsAngled, clang::CharSourceRange, clang::OptionalFileEntryRef, llvm::StringRef, llvm::StringRef, const clang::Module *, bool, clang::SrcMgr::CharacteristicKind) override
std::list< std::string > & fFilesIncludedByLinkdef
void EnteredSubmodule(clang::Module *M, clang::SourceLocation ImportLoc, bool ForPragma) override
TRootClingCallbacks(cling::Interpreter *interp, std::list< std::string > &filesIncludedByLinkdef)
Little helper class to bookkeep the files names which we want to make temporary.
void addFileName(std::string &nameStr)
Adds the name and the associated temp name to the catalog.
const std::string & getFileName(const std::string &tmpFileName)
std::vector< std::string > m_names
std::vector< std::string > m_tempNames
const std::string m_emptyString
std::string getTmpFileName(const std::string &filename)
static bool FromCygToNativePath(std::string &path)
std::string GetCurrentDir()
std::string MakePathRelative(const std::string &path, const std::string &base, bool isBuildingROOT=false)
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.
@ kInfo
Informational messages; used for instance for tracing.
@ kWarning
Warnings about likely unexpected behavior.
R__EXTERN SchemaRuleClassMap_t gReadRules
void GetRuleIncludes(std::list< std::string > &result)
Get the list of includes specified in the shema rules.
R__EXTERN SchemaRuleClassMap_t gReadRawRules
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
void header2outputName(std::string &fileName)
Replace the extension with "_rflx.cpp".
void AddToArgVectorSplit(std::vector< char * > &argvVector, const std::vector< std::string > &argsToBeAdded, const std::string &optName="")
void changeExtension(std::string &filename, const std::string &newExtension)
int invokeManyRootCling(const std::string &verbosity, const std::string &selectionFileName, const std::string &targetLibName, bool multiDict, const std::vector< std::string > &pcmsNames, const std::vector< std::string > &includes, const std::vector< std::string > &preprocDefines, const std::vector< std::string > &preprocUndefines, const std::vector< std::string > &warnings, const std::string &rootmapFileName, const std::string &rootmapLibName, bool interpreteronly, bool doSplit, bool isCxxmodule, bool writeEmptyRootPCM, bool selSyntaxOnly, bool noIncludePaths, bool noGlobalUsingStd, const std::vector< std::string > &headersNames, bool failOnWarnings, bool printRootclingInvocation, const std::string &outputDirName_const="")
Get the right ofilenames and invoke several times rootcling One invokation per header.
int invokeRootCling(const std::string &verbosity, const std::string &selectionFileName, const std::string &targetLibName, bool multiDict, const std::vector< std::string > &pcmsNames, const std::vector< std::string > &includes, const std::vector< std::string > &preprocDefines, const std::vector< std::string > &preprocUndefines, const std::vector< std::string > &warnings, const std::string &rootmapFileName, const std::string &rootmapLibName, bool interpreteronly, bool doSplit, bool isCxxmodule, bool writeEmptyRootPCM, bool selSyntaxOnly, bool noIncludePaths, bool noGlobalUsingStd, const std::vector< std::string > &headersNames, bool failOnWarnings, bool printRootclingInvocation, const std::string &ofilename)
unsigned int checkHeadersNames(std::vector< std::string > &headersNames)
Loop on arguments: stop at the first which starts with -.
void headers2outputsNames(const std::vector< std::string > &headersNames, std::vector< std::string > &ofilesnames)
Get a proper name for the output file.
char * string2charptr(const std::string &str)
The caller is responsible for deleting the string!
unsigned int extractArgs(int argc, char **argv, std::vector< std::string > &args)
Extract the arguments from the command line.
void AddToArgVector(std::vector< char * > &argvVector, const std::vector< std::string > &argsToBeAdded, const std::string &optName="")
int FinalizeStreamerInfoWriting(cling::Interpreter &interp, bool writeEmptyRootPCM=false)
Make up for skipping RegisterModule, now that dictionary parsing is done and these headers cannot be ...
int GenerateFullDict(std::ostream &dictStream, std::string dictName, cling::Interpreter &interp, RScanner &scan, const ROOT::TMetaUtils::RConstructorTypes &ctorTypes, bool isSplit, bool isGenreflex, bool isSelXML, bool writeEmptyRootPCM)
std::list< std::string > CollapseIdenticalNamespaces(const std::list< std::string > &fwdDeclarationsList)
If two identical namespaces are there, just declare one only Example: namespace A { namespace B { fwd...
static llvm::cl::opt< bool > gOptC("c", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::cat(gRootclingOptions))
void RiseWarningIfPresent(std::vector< ROOT::option::Option > &options, int optionIndex, const char *descriptor)
int RootClingMain(int argc, char **argv, bool isGenreflex=false)
static llvm::StringRef GetModuleNameFromRdictName(llvm::StringRef rdictName)
static llvm::cl::opt< bool > gOptGccXml("gccxml", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< std::string > gOptISysRoot("isysroot", llvm::cl::Prefix, llvm::cl::Hidden, llvm::cl::desc("Specify an isysroot."), llvm::cl::cat(gRootclingOptions), llvm::cl::init("-"))
int STLContainerStreamer(const clang::FieldDecl &m, int rwmode, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
Create Streamer code for an STL container.
std::string ExtractFileName(const std::string &path)
Extract the filename from a fullpath.
static llvm::cl::opt< bool > gOptRootBuild("rootbuild", llvm::cl::desc("If we are building ROOT."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
bool IsImplementationName(const std::string &filename)
const std::string gLibraryExtension(".so")
static llvm::cl::list< std::string > gOptSink(llvm::cl::ZeroOrMore, llvm::cl::Sink, llvm::cl::desc("Consumes all unrecognized options."), llvm::cl::cat(gRootclingOptions))
int GenReflexMain(int argc, char **argv)
Translate the arguments of genreflex into rootcling ones and forward them to the RootCling function.
static void MaybeSuppressWin32CrashDialogs()
void RecordDeclCallback(const clang::RecordDecl *recordDecl)
void CheckClassNameForRootMap(const std::string &classname, map< string, string > &autoloads)
bool Which(cling::Interpreter &interp, const char *fname, string &pname)
Find file name in path specified via -I statements to Cling.
void AdjustRootMapNames(std::string &rootmapFileName, std::string &rootmapLibName)
void AddNamespaceSTDdeclaration(std::ostream &dictStream)
static llvm::cl::list< std::string > gOptWDiags("W", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify compiler diagnostics options."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptCint("cint", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
static llvm::cl::list< std::string > gOptModuleByproducts("mByproduct", llvm::cl::ZeroOrMore, llvm::cl::Hidden, llvm::cl::desc("The list of the expected implicit modules build as part of building the current module."), llvm::cl::cat(gRootclingOptions))
map< string, string > gAutoloads
static llvm::cl::opt< bool > gOptCheckSelectionSyntax("selSyntaxOnly", llvm::cl::desc("Check the selection syntax only."), llvm::cl::cat(gRootclingOptions))
static bool CheckModuleValid(TModuleGenerator &modGen, const std::string &resourceDir, cling::Interpreter &interpreter, llvm::StringRef LinkdefPath, const std::string &moduleName)
Check moduleName validity from modulemap. Check if this module is defined or not.
static void CheckForMinusW(std::string arg, std::list< std::string > &diagnosticPragmas)
Transform -W statements in diagnostic pragmas for cling reacting on "-Wno-" For example -Wno-deprecat...
static bool WriteAST(llvm::StringRef fileName, clang::CompilerInstance *compilerInstance, llvm::StringRef iSysRoot, clang::Module *module=nullptr)
Write the AST of the given CompilerInstance to the given File while respecting the given isysroot.
static llvm::cl::opt< bool > gOptUmbrellaInput("umbrellaHeader", llvm::cl::desc("A single header including all headers instead of specifying them on the command line."), llvm::cl::cat(gRootclingOptions))
void ExtractFilePath(const std::string &path, std::string &dirname)
Extract the path from a fullpath finding the last \ or / according to the content in gPathSeparator.
int STLStringStreamer(const clang::FieldDecl &m, int rwmode, std::ostream &dictStream)
Create Streamer code for a standard string object.
void CreateDictHeader(std::ostream &dictStream, const std::string &main_dictname)
const char * GetExePath()
Returns the executable path name, used e.g. by SetRootSys().
const std::string gPathSeparator(ROOT::TMetaUtils::GetPathSeparator())
static llvm::cl::list< std::string > gOptBareClingSink(llvm::cl::OneOrMore, llvm::cl::Sink, llvm::cl::desc("Consumes options and sends them to cling."), llvm::cl::cat(gRootclingOptions), llvm::cl::sub(gBareClingSubcommand))
bool InheritsFromTObject(const clang::RecordDecl *cl, const cling::Interpreter &interp)
static bool InjectModuleUtilHeader(const char *argv0, TModuleGenerator &modGen, cling::Interpreter &interp, bool umbrella)
Write the extra header injected into the module: umbrella header if (umbrella) else content header.
static llvm::cl::list< std::string > gOptModuleMapFiles("moduleMapFile", llvm::cl::desc("Specify a C++ modulemap file."), llvm::cl::cat(gRootclingOptions))
int ExtractClassesListAndDeclLines(RScanner &scan, std::list< std::string > &classesList, std::list< std::string > &classesListForRootmap, std::list< std::string > &fwdDeclarationsList, const cling::Interpreter &interpreter)
void ParseRootMapFileNewFormat(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map, using the new format.
static llvm::cl::OptionCategory gRootclingOptions("rootcling common options")
static llvm::cl::list< std::string > gOptSysIncludePaths("isystem", llvm::cl::ZeroOrMore, llvm::cl::desc("Specify a system include path."), llvm::cl::cat(gRootclingOptions))
void ExtractHeadersForDecls(const RScanner::ClassColl_t &annotatedRcds, const RScanner::TypedefColl_t tDefDecls, const RScanner::FunctionColl_t funcDecls, const RScanner::VariableColl_t varDecls, const RScanner::EnumColl_t enumDecls, HeadersDeclsMap_t &headersClassesMap, HeadersDeclsMap_t &headersDeclsMap, const cling::Interpreter &interp)
bool ParsePragmaLine(const std::string &line, const char *expectedTokens[], size_t *end=nullptr)
Check whether the #pragma line contains expectedTokens (0-terminated array).
static llvm::cl::opt< bool > gOptWriteEmptyRootPCM("writeEmptyRootPCM", llvm::cl::Hidden, llvm::cl::desc("Does not include the header files as it assumes they exist in the pch."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptGeneratePCH("generate-pch", llvm::cl::desc("Generates a pch file from a predefined set of headers. See makepch.py."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
static bool ModuleContainsHeaders(TModuleGenerator &modGen, clang::HeaderSearch &headerSearch, clang::Module *module, std::vector< std::array< std::string, 2 > > &missingHeaders)
Returns true iff a given module (and its submodules) contains all headers needed by the given ModuleG...
static bool GenerateAllDict(TModuleGenerator &modGen, clang::CompilerInstance *compilerInstance, const std::string ¤tDirectory)
Generates a PCH from the given ModuleGenerator and CompilerInstance.
void LoadLibraryMap(const std::string &fileListName, map< string, string > &autoloads)
Fill the map of libraries to be loaded in presence of a class Transparently support the old and new r...
std::ostream * CreateStreamPtrForSplitDict(const std::string &dictpathname, tempFileNamesCatalog &tmpCatalog)
Transform name of dictionary.
void WriteNamespaceInit(const clang::NamespaceDecl *cl, cling::Interpreter &interp, std::ostream &dictStream)
Write the code to initialize the namespace name and the initialization object.
static llvm::cl::list< std::string > gOptCompDefaultIncludePaths("compilerI", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify a compiler default include path, to suppress unneeded `-isystem` arguments."), llvm::cl::cat(gRootclingOptions))
void AnnotateAllDeclsForPCH(cling::Interpreter &interp, RScanner &scan)
We need annotations even in the PCH: // !, // || etc.
size_t GetFullArrayLength(const clang::ConstantArrayType *arrayType)
static llvm::cl::opt< bool > gOptSplit("split", llvm::cl::desc("Split the dictionary into two parts: one containing the IO (ClassDef)\
information and another the interactivity support."), llvm::cl::cat(gRootclingOptions))
bool ProcessAndAppendIfNotThere(const std::string &el, std::list< std::string > &el_list, std::unordered_set< std::string > &el_set)
Separate multiline strings.
static llvm::cl::opt< bool > gOptNoGlobalUsingStd("noGlobalUsingStd", llvm::cl::desc("Do not declare {using namespace std} in dictionary global scope."), llvm::cl::cat(gRootclingOptions))
const ROOT::Internal::RootCling::DriverConfig * gDriverConfig
static llvm::cl::list< std::string > gOptModuleDependencies("m", llvm::cl::desc("The list of dependent modules of the dictionary."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::SubCommand gBareClingSubcommand("bare-cling", "Call directly cling and exit.")
static llvm::cl::opt< bool > gOptInterpreterOnly("interpreteronly", llvm::cl::desc("Generate minimal dictionary for interactivity (without IO information)."), llvm::cl::cat(gRootclingOptions))
void WriteArrayDimensions(const clang::QualType &type, std::ostream &dictStream)
Write "[0]" for all but the 1st dimension.
static llvm::cl::opt< bool > gOptReflex("reflex", llvm::cl::desc("Behave internally like genreflex."), llvm::cl::cat(gRootclingOptions))
void GetMostExternalEnclosingClassName(const clang::DeclContext &theContext, std::string &ctxtName, const cling::Interpreter &interpreter, bool treatParent=true)
Extract the proper autoload key for nested classes The routine does not erase the name,...
std::string GetFwdDeclnArgsToKeepString(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, cling::Interpreter &interp)
int ExtractAutoloadKeys(std::list< std::string > &names, const COLL &decls, const cling::Interpreter &interp)
static llvm::cl::opt< std::string > gOptSharedLibFileName("s", llvm::cl::desc("The path to the library of the built dictionary."), llvm::cl::cat(gRootclingOptions))
void WriteStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
int ROOT_rootcling_Driver(int argc, char **argv, const ROOT::Internal::RootCling::DriverConfig &config)
bool IsGoodForAutoParseMap(const clang::RecordDecl &rcd)
Check if the class good for being an autoparse key.
std::map< std::string, std::list< std::string > > HeadersDeclsMap_t
#define rootclingStringify(s)
void GetMostExternalEnclosingClassNameFromDecl(const clang::Decl &theDecl, std::string &ctxtName, const cling::Interpreter &interpreter)
static llvm::cl::opt< bool > gOptP("p", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::cat(gRootclingOptions))
bool CheckInputOperator(const char *what, const char *proto, const string &fullname, const clang::RecordDecl *cl, cling::Interpreter &interp)
Check if the specified operator (what) has been properly declared if the user has requested a custom ...
void GenerateNecessaryIncludes(std::ostream &dictStream, const std::string &includeForSource, const std::string &extraIncludes)
void StrcpyArg(string &dest, const char *original)
Copy the command line argument, stripping MODULE/inc if necessary.
static llvm::cl::list< std::string > gOptRootmapLibNames("rml", llvm::cl::ZeroOrMore, llvm::cl::desc("Generate rootmap file."), llvm::cl::cat(gRootclingOptions))
void ParseRootMapFile(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map.
static llvm::cl::opt< bool > gOptCxxModule("cxxmodule", llvm::cl::desc("Generate a C++ module."), llvm::cl::cat(gRootclingOptions))
std::pair< std::string, std::string > GetExternalNamespaceAndContainedEntities(const std::string line)
Performance is not critical here.
void AddPlatformDefines(std::vector< std::string > &clingArgs)
static std::string GenerateFwdDeclString(const RScanner &scan, const cling::Interpreter &interp)
Generate the fwd declarations of the selected entities.
static llvm::cl::opt< bool > gOptFailOnWarnings("failOnWarnings", llvm::cl::desc("Fail if there are warnings."), llvm::cl::cat(gRootclingOptions))
const char * CopyArg(const char *original)
If the argument starts with MODULE/inc, strip it to make it the name we can use in #includes.
string GetNonConstMemberName(const clang::FieldDecl &m, const string &prefix="")
Return the name of the data member so that it can be used by non-const operation (so it includes a co...
static llvm::cl::list< std::string > gOptIncludePaths("I", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify an include path."), llvm::cl::cat(gRootclingOptions))
void WriteAutoStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
void ExtractSelectedNamespaces(RScanner &scan, std::list< std::string > &nsList)
Loop on selected classes and put them in a list.
static bool IncludeHeaders(const std::vector< std::string > &headers, cling::Interpreter &interpreter)
Includes all given headers in the interpreter.
clang::QualType GetPointeeTypeIfPossible(const clang::QualType &qt)
Get the pointee type if possible.
void AnnotateDecl(clang::CXXRecordDecl &CXXRD, const RScanner::DeclsSelRulesMap_t &declSelRulesMap, cling::Interpreter &interpreter, bool isGenreflex)
static llvm::cl::opt< VerboseLevel > gOptVerboseLevel(llvm::cl::desc("Choose verbosity level:"), llvm::cl::values(clEnumVal(v, "Show errors."), clEnumVal(v0, "Show only fatal errors."), clEnumVal(v1, "Show errors (the same as -v)."), clEnumVal(v2, "Show warnings (default)."), clEnumVal(v3, "Show notes."), clEnumVal(v4, "Show information.")), llvm::cl::init(v2), llvm::cl::cat(gRootclingOptions))
void GenerateLinkdef(llvm::cl::list< std::string > &InputFiles, std::string &code_for_parser)
static llvm::cl::opt< std::string > gOptRootMapFileName("rmf", llvm::cl::desc("Generate a rootmap file with the specified name."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptInlineInput("inlineInputHeader", llvm::cl::desc("Does not generate #include <header> but expands the header content."), llvm::cl::cat(gRootclingOptions))
bool isPointerToPointer(const clang::FieldDecl &m)
int CreateNewRootMapFile(const std::string &rootmapFileName, const std::string &rootmapLibName, const std::list< std::string > &classesDefsList, const std::list< std::string > &classesNames, const std::list< std::string > &nsNames, const std::list< std::string > &tdNames, const std::list< std::string > &enNames, const std::list< std::string > &varNames, const HeadersDeclsMap_t &headersClassesMap, const std::unordered_set< std::string > headersToIgnore)
Generate a rootmap file in the new format, like { decls } namespace A { namespace B { template <typen...
static llvm::cl::opt< std::string > gOptDictionaryFileName(llvm::cl::Positional, llvm::cl::desc("<output dictionary file>"), llvm::cl::cat(gRootclingOptions))
bool IsSelectionXml(const char *filename)
bool IsGoodLibraryName(const std::string &name)
llvm::StringRef GrabIndex(const cling::Interpreter &interp, const clang::FieldDecl &member, int printError)
GrabIndex returns a static string (so use it or copy it immediately, do not call GrabIndex twice in t...
static llvm::cl::opt< bool > gOptMultiDict("multiDict", llvm::cl::desc("If this library has multiple separate LinkDef files."), llvm::cl::cat(gRootclingOptions))
bool IsSelectionFile(const char *filename)
const std::string GenerateStringFromHeadersForClasses(const HeadersDeclsMap_t &headersClassesMap, const std::string &detectedUmbrella, bool payLoadOnly=false)
Generate a string for the dictionary from the headers-classes map.
bool IsSupportedClassName(const char *name)
static llvm::cl::opt< bool > gOptForce("f", llvm::cl::desc("Overwrite <file>s."), llvm::cl::cat(gRootclingOptions))
static void AnnotateFieldDecl(clang::FieldDecl &decl, const std::list< VariableSelectionRule > &fieldSelRules)
void CallWriteStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream, bool isAutoStreamer)
static llvm::cl::list< std::string > gOptPPUndefines("U", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify undefined macros."), llvm::cl::cat(gRootclingOptions))
int CheckClassesForInterpreterOnlyDicts(cling::Interpreter &interp, RScanner &scan)
bool InheritsFromTSelector(const clang::RecordDecl *cl, const cling::Interpreter &interp)
static void EmitTypedefs(const std::vector< const clang::TypedefNameDecl * > &tdvec)
bool Namespace__HasMethod(const clang::NamespaceDecl *cl, const char *name, const cling::Interpreter &interp)
static llvm::cl::list< std::string > gOptPPDefines("D", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify defined macros."), llvm::cl::cat(gRootclingOptions))
bool IsCorrectClingArgument(const std::string &argument)
Check if the argument is a sane cling argument.
bool IsLinkdefFile(const clang::PresumedLoc &PLoc)
void WriteClassFunctions(const clang::CXXRecordDecl *cl, std::ostream &dictStream, bool autoLoad=false)
Write the code to set the class name and the initialization object.
static llvm::cl::list< std::string > gOptExcludePaths("excludePath", llvm::cl::ZeroOrMore, llvm::cl::desc("Do not store the <path> in the dictionary."), llvm::cl::cat(gRootclingOptions))
std::list< std::string > RecordDecl2Headers(const clang::CXXRecordDecl &rcd, const cling::Interpreter &interp, std::set< const clang::CXXRecordDecl * > &visitedDecls)
Extract the list of headers necessary for the Decl.
void EmitStreamerInfo(const char *normName)
static llvm::cl::opt< bool > gOptNoIncludePaths("noIncludePaths", llvm::cl::desc("Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."), llvm::cl::cat(gRootclingOptions))
bool HasPath(const std::string &name)
Check if file has a path.
static llvm::cl::opt< std::string > gOptLibListPrefix("lib-list-prefix", llvm::cl::desc("An ACLiC feature which exports the list of dependent libraries."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptNoDictSelection("noDictSelection", llvm::cl::Hidden, llvm::cl::desc("Do not run the selection rules. Useful when in -onepcm mode."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::list< std::string > gOptDictionaryHeaderFiles(llvm::cl::Positional, llvm::cl::ZeroOrMore, llvm::cl::desc("<list of dictionary header files> <LinkDef file | selection xml file>"), llvm::cl::cat(gRootclingOptions))
int CheckForUnsupportedClasses(const RScanner::ClassColl_t &annotatedRcds)
Check if the list of selected classes contains any class which is not supported.
static void EmitEnums(const std::vector< const clang::EnumDecl * > &enumvec)
static llvm::cl::opt< bool > gOptSystemModuleByproducts("mSystemByproducts", llvm::cl::Hidden, llvm::cl::desc("Allow implicit build of system modules."), llvm::cl::cat(gRootclingOptions))
bool CheckClassDef(const clang::RecordDecl &cl, const cling::Interpreter &interp)
Return false if the class does not have ClassDef even-though it should.
bool NeedsSelection(const char *name)
int extractMultipleOptions(std::vector< ROOT::option::Option > &options, int oIndex, std::vector< std::string > &values)
Extract from options multiple values with the same option.
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Describes an option, its help text (usage) and how it should be parsed.
static option::ArgStatus Required(const option::Option &option, bool msg)
Determines the minimum lengths of the buffer and options arrays used for Parser.
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...