12#include "rootclingCommandLineOptionsHelp.h"
14#include "RConfigure.h"
32#include <unordered_map>
33#include <unordered_set>
45#define PATH_MAX _MAX_PATH
53#include <mach-o/dyld.h>
61#include <libprocstat.h>
70#include "cling/Interpreter/Interpreter.h"
71#include "cling/Interpreter/InterpreterCallbacks.h"
72#include "cling/Interpreter/LookupHelper.h"
73#include "cling/Interpreter/Value.h"
74#include "clang/AST/CXXInheritance.h"
75#include "clang/Basic/Diagnostic.h"
76#include "clang/Frontend/CompilerInstance.h"
77#include "clang/Frontend/FrontendActions.h"
78#include "clang/Frontend/FrontendDiagnostic.h"
79#include "clang/Lex/HeaderSearch.h"
80#include "clang/Lex/Preprocessor.h"
81#include "clang/Lex/ModuleMap.h"
82#include "clang/Lex/Pragma.h"
83#include "clang/Sema/Sema.h"
84#include "clang/Serialization/ASTWriter.h"
85#include "cling/Utils/AST.h"
87#include "llvm/ADT/StringRef.h"
89#include "llvm/Support/CommandLine.h"
90#include "llvm/Support/Path.h"
91#include "llvm/Support/PrettyStackTrace.h"
92#include "llvm/Support/Signals.h"
106#include "OptionParser.h"
116#include <mach-o/dyld.h>
121#define strcasecmp _stricmp
122#define strncasecmp _strnicmp
130#define rootclingStringify(s) rootclingStringifyx(s)
131#define rootclingStringifyx(s) #s
138using std::string, std::map, std::ifstream, std::ofstream, std::endl, std::ios, std::vector;
160 gDriverConfig->fAddTypedefToROOTFile(
td->getQualifiedNameAsString().c_str());
168 if (clang::isa<clang::TranslationUnitDecl>(
en->getDeclContext())
169 || clang::isa<clang::LinkageSpecDecl>(
en->getDeclContext())
170 || clang::isa<clang::NamespaceDecl>(
en->getDeclContext()))
171 gDriverConfig->fAddEnumToROOTFile(
en->getQualifiedNameAsString().c_str());
185#if defined(__linux) || defined(__linux__)
194 if (
ret > 0 &&
ret < 1024) {
228 const cling::Interpreter &
interp)
246 clang::ASTContext &C =
decl.getASTContext();
252 if (! it->GetAttributeValue(propNames::name,
varName))
continue;
256 BaseSelectionRule::AttributesMap_t::iterator iter;
259 const std::string &
name = iter->first;
260 const std::string &
value = iter->second;
262 if (
name == propNames::name)
continue;
267 if (
name == propNames::iotype &&
268 (
decl.getType()->isArrayType() ||
decl.getType()->isPointerType())) {
269 const char *
msg =
"Data member \"%s\" is an array or a pointer. "
270 "It is not possible to assign to it the iotype \"%s\". "
271 "This transformation is possible only with data members "
272 "which are not pointers or arrays.\n";
282 if (
name == propNames::comment) {
283 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
value,
nullptr, 0));
287 if ((
name == propNames::transient &&
value ==
"true") ||
288 (
name == propNames::persistent &&
value ==
"false")) {
293 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
"!",
nullptr, 0));
319 using namespace clang;
321 llvm::StringRef comment;
338 BaseSelectionRule::AttributesMap_t::iterator iter;
341 const std::string &
name =
attr.first;
353 for (CXXRecordDecl::decl_iterator I =
CXXRD.decls_begin(),
354 E =
CXXRD.decls_end(); I != E; ++I) {
358 if (!(*I)->isImplicit()
370 if (comment.size()) {
373 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
380 (*I)->addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
404 while (
const clang::ConstantArrayType *
subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual())) {
408 return len.getLimitedValue();
414 const cling::Interpreter &
interp)
419 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
426 const cling::Interpreter &
interp)
466 size_t *end =
nullptr)
469 if (
line[0] !=
'#')
return false;
494 clang::Module *M =
recordDecl->getOwningModule()->getTopLevelModule();
512 if (classname.find(
':') == std::string::npos)
return;
515 int slen = classname.size();
516 for (
int k = 0; k <
slen; ++k) {
517 if (classname[k] ==
':') {
518 if (k + 1 >=
slen || classname[k + 1] !=
':') {
523 string base = classname.substr(0, k);
532 }
else if (classname[k] ==
'<') {
544 std::string classname;
546 while (file >>
line) {
548 if (
line.find(
"Library.") != 0)
continue;
550 int pos =
line.find(
":", 8);
551 classname =
line.substr(8, pos - 8);
557 while (
line[0] ==
' ')
line.replace(0, 1,
"");
561 if (classname ==
"ROOT::TImpProxy") {
580 const std::unordered_map<char, unsigned int>
keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
583 if (
line ==
"{ decls }") {
585 if (
line[0] ==
'[')
break;
592 while (
libs[0] ==
' ')
libs.replace(0, 1,
"");
616 if (llvm::sys::fs::is_directory(
filename))
continue;
624 file.seekg(0, std::ios::beg);
645 const string &fullname,
646 const clang::RecordDecl *cl,
647 cling::Interpreter &
interp)
650 const clang::FunctionDecl *
method
655 clang::TranslationUnitDecl *
TU =
656 cl->getASTContext().getTranslationUnitDecl();
661 if (
method !=
nullptr && (
method->getAccess() == clang::AS_public ||
method->getAccess() == clang::AS_none)) {
680 "in this version of ROOT, the option '!' used in a linkdef file\n"
681 " implies the actual existence of customized operators.\n"
682 " The following declaration is now required:\n"
697 int ncha = fullname.length() + 13;
722 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
733 "because it inherits from TObject but does not "
734 "have its own ClassDef.\n",
747 if (
m.getType().isConstQualified()) {
748 string ret =
"const_cast< ";
758 ret +=
m.getName().str();
762 return prefix +
m.getName().str();
772 const cling::Interpreter &
interp,
790 if (!
clxx ||
clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
792 const clang::ClassTemplateSpecializationDecl *
tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (
clxx);
800 const char *
tcl1 =
nullptr, *
tcl2 =
nullptr;
802 clang::QualType
ti =
arg0.getAsType();
820 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
826 if (
arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
830 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
832 }
else if (
m.getType()->isPointerType()) {
839 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
851 <<
" *" <<
stlName.c_str() <<
" = new " <<
stlType.c_str() <<
";" << std::endl
852 <<
" " <<
stlType.c_str() <<
" &R__stl = **" <<
stlName.c_str() <<
";" << std::endl;
856 <<
" " <<
stlName.c_str() <<
"[R__l] = new " <<
stlType.c_str() <<
";" << std::endl
857 <<
" " <<
stlType.c_str() <<
" &R__stl = *" <<
stlName.c_str() <<
"[R__l];" << std::endl;
861 dictStream <<
" R__stl.clear();" << std::endl;
864 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
865 <<
" if (R__tcl1==0) {" << std::endl
866 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
867 <<
fulName1.c_str() <<
"!\");" << std::endl
868 <<
" return;" << std::endl
869 <<
" }" << std::endl;
872 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
873 <<
" if (R__tcl2==0) {" << std::endl
874 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
875 <<
fulName2.c_str() <<
"!\");" << std::endl
876 <<
" return;" << std::endl
877 <<
" }" << std::endl;
881 <<
" R__b >> R__n;" << std::endl;
884 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
886 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
912 <<
" std::pair<Value_t const, " <<
tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
913 <<
" R__stl.insert(R__t3);" << std::endl;
921 dictStream <<
" R__stl.insert(R__t);" << std::endl;
926 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
929 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
935 <<
" }" << std::endl;
942 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
960 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
961 <<
" R__b << R__n;" << std::endl
962 <<
" if(R__n) {" << std::endl;
965 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
966 <<
" if (R__tcl1==0) {" << std::endl
967 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
968 <<
fulName1.c_str() <<
"!\");" << std::endl
969 <<
" return;" << std::endl
970 <<
" }" << std::endl;
973 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
974 <<
" if (R__tcl2==0) {" << std::endl
975 <<
" Error(\"" <<
stlName.c_str() <<
"streamer\",\"Missing the TClass object for " <<
fulName2.c_str() <<
"!\");" << std::endl
976 <<
" return;" << std::endl
977 <<
" }" << std::endl;
981 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
993 <<
" }" << std::endl;
1015 if (
m.getType()->isConstantArrayType()) {
1016 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1017 dictStream <<
"// Array of pointer to std::string are not supported (" <<
fieldname <<
"\n";
1020 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1023 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1024 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1025 fullIdx <<
"[R__i" << dim <<
"]";
1026 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1029 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1033 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1034 if (
m.getType()->isPointerType())
1036 <<
fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1042 if (
m.getType()->isPointerType())
1044 <<
fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1045 else if (
m.getType()->isConstantArrayType()) {
1047 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1050 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1051 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1052 fullIdx <<
"[R__i" << dim <<
"]";
1053 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1058 dictStream <<
" { TString R__str = " <<
fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1069 if (
m.getType()->isPointerType()) {
1070 if (
m.getType()->getPointeeType()->isPointerType()) {
1082 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1084 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1087 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1109 dictStream <<
"#include \"TInterpreter.h\"\n";
1111 dictStream <<
"//_______________________________________"
1112 <<
"_______________________________________" << std::endl;
1114 dictStream <<
"atomic_TClass_ptr " <<
clsname <<
"::fgIsA(nullptr); // static to hold class pointer" << std::endl
1117 <<
"//_______________________________________"
1118 <<
"_______________________________________" << std::endl;
1120 dictStream <<
"const char *" <<
clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1121 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1123 dictStream <<
"//_______________________________________"
1124 <<
"_______________________________________" << std::endl;
1126 dictStream <<
"const char *" <<
clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1127 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1128 <<
"*)nullptr)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1130 <<
"//_______________________________________"
1131 <<
"_______________________________________" << std::endl;
1133 dictStream <<
"int " <<
clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1134 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1135 <<
"*)nullptr)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1137 <<
"//_______________________________________"
1138 <<
"_______________________________________" << std::endl;
1140 dictStream <<
"TClass *" <<
clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1144 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1145 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1146 <<
"*)nullptr)->GetClass();" << std::endl
1147 <<
" return fgIsA;\n"
1148 <<
"}" << std::endl << std::endl
1150 <<
"//_______________________________________"
1151 <<
"_______________________________________" << std::endl;
1153 dictStream <<
"TClass *" <<
clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1157 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1158 dictStream << fullname <<
"*)nullptr)->GetClass(); }" << std::endl;
1161 <<
"}" << std::endl << std::endl;
1173 cling::Interpreter &
interp,
1176 if (cl->isAnonymousNamespace()) {
1188 if (classname !=
"ROOT") {
1192 dictStream <<
" namespace ROOTDict {" << std::endl;
1194 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1200 <<
" // Function generating the singleton type initializer" << std::endl
1202 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1203 <<
" {" << std::endl
1205 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1207 <<
" instance(\"" << classname.c_str() <<
"\", ";
1210 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1216 for (
unsigned int i = 0; i <
filename.length(); i++) {
1220 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1224 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1231 <<
" return &instance;" << std::endl
1232 <<
" }" << std::endl
1233 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1234 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1235 <<
" // Static variable to force the class initialization" << std::endl
1237 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1238 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1241 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1242 <<
" static TClass *" <<
mappedname.c_str() <<
"_Dictionary() {" << std::endl
1243 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1244 <<
" }" << std::endl << std::endl;
1263 llvm::StringRef
where;
1273 errorstring =
"has not been defined before the array";
1276 errorstring =
"is a private member of a parent class";
1285 if (
where.size() == 0) {
1287 member.getParent()->getName().str().c_str(),
member.getName().str().c_str());
1299 const cling::Interpreter &
interp,
1303 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1304 if (
clxx ==
nullptr)
return;
1317 dictStream <<
"//_______________________________________"
1318 <<
"_______________________________________" << std::endl;
1320 dictStream <<
"void " <<
clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1321 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1330 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1339 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1341 <<
" baseClass" <<
basestreamer <<
"::Streamer(R__b);" << std::endl;
1349 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1350 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1361 string classname = fullname;
1362 if (
strstr(fullname.c_str(),
"::")) {
1364 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1365 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1366 classname =
"thisClass";
1368 for (
int i = 0; i < 2; i++) {
1373 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1374 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1375 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1377 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1379 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1384 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1393 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1394 <<
" typedef " <<
base_fullname <<
" baseClass" << base <<
";" << std::endl
1395 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1404 for (clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
1410 std::string
type_name =
type.getAsString(
clxx->getASTContext().getPrintingPolicy());
1427 if (
strncmp(comment,
"!", 1)) {
1431 if (
type.getTypePtr()->isConstantArrayType() &&
1432 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1433 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1440 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1442 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());
1445 dictStream <<
" ;//R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1447 }
else if (
type.getTypePtr()->isPointerType()) {
1451 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer 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;
1463 <<
"," <<
indexvar.str() <<
");" << std::endl;
1466 <<
"," <<
indexvar.str() <<
");" << std::endl;
1469 <<
"," <<
indexvar.str() <<
");" << std::endl;
1476 dictStream <<
" R__b.WriteFastArrayDouble32("
1484 }
else if (
type.getTypePtr()->isArrayType()) {
1486 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1488 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1492 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1495 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1498 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1503 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1506 dictStream <<
" R__b.ReadStaticArrayFloat16(" <<
field_iter->getName().str() <<
");" << std::endl;
1508 dictStream <<
" R__b.ReadStaticArrayDouble32(" <<
field_iter->getName().str() <<
");" << std::endl;
1511 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1516 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1519 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1522 << s <<
");" << std::endl;
1525 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1528 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1531 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1535 dictStream <<
" R__b.WriteArray((Int_t*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1537 dictStream <<
" R__b.WriteArrayFloat16(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1539 dictStream <<
" R__b.WriteArrayDouble32(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1541 dictStream <<
" R__b.WriteArray(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1548 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" <<
field_iter->getName().str() <<
");" << std::endl;
1555 <<
"=Float16_t(R_Dummy);}" << std::endl;
1561 <<
"=Double32_t(R_Dummy);}" << std::endl;
1583 if (
type.getTypePtr()->isConstantArrayType() &&
1584 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1585 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1592 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1603 }
else if (
type.getTypePtr()->isPointerType()) {
1611 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1638 }
else if (
const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1645 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1649 const char *
constwd =
"const ";
1654 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1658 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1665 <<
field_iter->getName().str() <<
"));" << std::endl;
1676 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1677 <<
" }" << std::endl
1678 <<
"}" << std::endl << std::endl;
1689 const cling::Interpreter &
interp,
1695 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1696 if (
clxx ==
nullptr)
return;
1701 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1719 dictStream <<
"//_______________________________________"
1720 <<
"_______________________________________" << std::endl;
1724 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1725 <<
" if (R__b.IsReading()) {" << std::endl
1726 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1727 <<
" } else {" << std::endl
1728 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1729 <<
" }" << std::endl
1730 <<
"}" << std::endl << std::endl;
1741 const cling::Interpreter &
interp,
1780 for (
size_t i = 0; i <
nPaths; i += 1 ) {
1829 cling::Interpreter &
interp,
1832 std::ostringstream out;
1836 modGen.WriteUmbrellaHeader(out);
1837 if (
interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1845 modGen.WriteContentHeader(out);
1858 clang::Module *
module =
nullptr)
1861 llvm::SmallVector<char, 128> buffer;
1862 llvm::BitstreamWriter stream(buffer);
1864 std::unique_ptr<llvm::raw_ostream> out =
1879 out->write(&buffer.front(), buffer.size());
1893 assert(
modGen.IsPCH() &&
"modGen must be in PCH mode");
1895 std::string
iSysRoot(
"/DUMMY_SYSROOT/include/");
1910 std::stringstream includes;
1911 for (
const std::string &header :
headers) {
1912 includes <<
"#include \"" << header <<
"\"\n";
1916 return result == cling::Interpreter::CompilationResult::kSuccess;
1925#ifdef __INTEL_COMPILER
1938#ifdef __GNUC_MINOR__
1954#ifdef _STLPORT_VERSION
1993#if defined(_WIN64) && defined(_DEBUG)
2005 return llvm::sys::path::filename(path).str();
2015 if (std::string::npos != pos) {
2016 dirname.assign(path.begin(), path.begin() + pos + 1);
2084 const cling::Interpreter &
interp)
2086 if (!
decls.empty()) {
2093 names.push_back(
d->getQualifiedNameAsString());
2114 const std::list<std::string> &
nsNames,
2115 const std::list<std::string> &
tdNames,
2116 const std::list<std::string> &
enNames,
2117 const std::list<std::string> &
varNames,
2151 rootmapFile <<
"class " << className << std::endl;
2158 if (className.find(
"<") != std::string::npos)
continue;
2162 auto &header =
headers.front();
2183 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2192 rootmapFile <<
"# List of selected enums and outer classes\n";
2219 if (
foundNsPos == std::string::npos)
return {
"",
""};
2275 std::list<std::string> &
el_list,
2276 std::unordered_set<std::string> &
el_set)
2334 std::cerr <<
"FATAL: A class with normalized name " <<
normalizedName
2335 <<
" was already selected. This means that two different instances of"
2336 <<
" clang::RecordDecl had the same name, which is not possible."
2337 <<
" This can be a hint of a serious problem in the class selection."
2338 <<
" In addition, the generated dictionary would not even compile.\n";
2352 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl)) {
2394 !llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl) &&
2448 if (clang::CXXRecordDecl *
CXXRD =
2449 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2461 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2464 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2467 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2483 if (
interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2484 "#include \"TFile.h\"\n"
2485 "#include \"TObjArray.h\"\n"
2486 "#include \"TVirtualArray.h\"\n"
2487 "#include \"TStreamerElement.h\"\n"
2488 "#include \"TProtoClass.h\"\n"
2489 "#include \"TBaseClass.h\"\n"
2490 "#include \"TListOfDataMembers.h\"\n"
2491 "#include \"TListOfEnums.h\"\n"
2492 "#include \"TListOfEnumsWithLock.h\"\n"
2493 "#include \"TDataMember.h\"\n"
2494 "#include \"TEnum.h\"\n"
2495 "#include \"TEnumConstant.h\"\n"
2496 "#include \"TDictAttributeMap.h\"\n"
2497 "#include \"TMessageHandler.h\"\n"
2498 "#include \"TArray.h\"\n"
2499 "#include \"TRefArray.h\"\n"
2500 "#include \"root_std_complex.h\"\n")
2501 != cling::Interpreter::kSuccess)
2537 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2538 if (
nsName.find(
"(anonymous)") == std::string::npos)
2543 if (!
selClass.GetRecordDecl()->isCompleteDefinition()) {
2547 if (
selClass.RequestOnlyTClass()) {
2555 if (clang::CXXRecordDecl *
CXXRD =
2556 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2560 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2568 }
else if (
CRD->getName() ==
"RVec") {
2569 static const clang::DeclContext *
vecOpsDC =
nullptr;
2571 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2572 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2594 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2598 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2610 if (!
selClass.GetRecordDecl()->isCompleteDefinition() || !
selClass.RequestOnlyTClass()) {
2614 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2660 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2661 <<
"#define R__DICTIONARY_FILENAME " <<
main_dictname << std::endl
2664 <<
"#define R__NO_DEPRECATION" << std::endl
2669 <<
"\n/*******************************************************************/\n"
2670 <<
"#include <cstddef>\n"
2671 <<
"#include <cstdio>\n"
2672 <<
"#include <cstdlib>\n"
2673 <<
"#include <cstring>\n"
2674 <<
"#include <cassert>\n"
2675 <<
"#define G__DICTIONARY\n"
2676 <<
"#include \"ROOT/RConfig.hxx\"\n"
2677 <<
"#include \"TClass.h\"\n"
2678 <<
"#include \"TDictAttributeMap.h\"\n"
2679 <<
"#include \"TInterpreter.h\"\n"
2680 <<
"#include \"TROOT.h\"\n"
2681 <<
"#include \"TBuffer.h\"\n"
2682 <<
"#include \"TMemberInspector.h\"\n"
2683 <<
"#include \"TInterpreter.h\"\n"
2684 <<
"#include \"TVirtualMutex.h\"\n"
2685 <<
"#include \"TError.h\"\n\n"
2686 <<
"#ifndef G__ROOT\n"
2687 <<
"#define G__ROOT\n"
2689 <<
"#include \"RtypesImp.h\"\n"
2690 <<
"#include \"TIsAProxy.h\"\n"
2691 <<
"#include \"TFileMergeInfo.h\"\n"
2692 <<
"#include <algorithm>\n"
2693 <<
"#include \"TCollectionProxyInfo.h\"\n"
2694 <<
"/*******************************************************************/\n\n"
2695 <<
"#include \"TDataMember.h\"\n\n";
2702 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2703 <<
"namespace std {} using namespace std;\n\n";
2712 dictStream <<
"// Header files passed as explicit arguments\n"
2714 <<
"// Header files passed via #pragma extra_include\n"
2721#if defined(R__IOSSIM) || defined(R__IOS)
2782 for (
unsigned int i = 0; i <
m_size; ++i) {
2790 if (
ifile.is_open())
2792 if (0 != std::remove(
tmpName)) {
2805 for (
unsigned int i = 0; i <
m_size; ++i) {
2814 if (
ifile.is_open())
2822 llvm::sys::fs::remove(
tmpName);
2847 std::cout <<
"Restoring files in temporary file catalog:\n";
2848 for (
unsigned int i = 0; i <
m_size; ++i) {
2881 static const std::string pattern(
"-Wno-");
2883 if (arg.find(pattern) != 0)
2894 cling::Interpreter &
interp)
2919 if (
qt.isNull())
return qt;
2921 while (
thisQt->isPointerType() ||
2922 thisQt->isReferenceType()) {
2933 const cling::Interpreter &
interp,
2936 std::list<std::string>
headers;
2939 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
2946 if (
const clang::ClassTemplateSpecializationDecl *
tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&
rcd)) {
2949 for (
auto &
tArg :
tsd->getTemplateArgs().asArray()) {
2950 if (clang::TemplateArgument::ArgKind::Type !=
tArg.getKind())
continue;
2971 if (
const clang::FieldDecl *
fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*
declIt)) {
2984 for (
auto & fPar :
methodIt->parameters()) {
3019 if (!
dclCtxt->isStdNamespace()){
3039 if (
argKind != clang::TemplateArgument::Type){
3040 if (
argKind == clang::TemplateArgument::Integral)
continue;
3047 if (
isPOD)
continue;
3072 const cling::Interpreter &
interp)
3075 std::unordered_set<std::string> buffer;
3080 if (
const clang::CXXRecordDecl *
cxxRcd =
3081 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
annotatedRcd.GetRecordDecl())) {
3087 headers.remove_if([&buffer](
const std::string & s) {
3088 return !buffer.insert(s).second;
3101 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(
cxxRcd)){
3110 if (clang::CXXRecordDecl *
cxxRcd =
tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3117 headers.remove_if([&buffer](
const std::string & s) {
3118 return !buffer.insert(s).second;
3149 const cling::Interpreter &
interp)
3157 std::unordered_set<std::string>
fwdDecls;
3200 std::cout <<
"Logs from forward decl printer: \n"
3231 std::cout <<
"Class-headers Mapping:\n";
3247 std::cout << std::endl;
3274 static const std::vector<std::string>
namePrfxes {
3279 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3297 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3311 std::cerr <<
"Error: Class " <<
clName <<
" has been selected but "
3312 <<
"currently the support for its I/O is not yet available. Note that "
3313 <<
clName <<
", even if not selected, will be available for "
3314 <<
"interpreted code.\n";
3318 std::cerr <<
"Error: It is not necessary to explicitly select class "
3319 <<
clName <<
". I/O is supported for it transparently.\n";
3334 InterpreterCallbacks(
interp),
3340 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3341 clang::OptionalFileEntryRef , llvm::StringRef ,
3342 llvm::StringRef ,
const clang::Module * ,
bool ,
3343 clang::SrcMgr::CharacteristicKind )
override
3378 using namespace clang;
3379 if (llvm::StringRef(M->Name).ends_with(
"ACLiC_dict")) {
3385 assert(M &&
"Must have module Core");
3392 llvm::cl::desc(
"Allow implicit build of system modules."),
3394static llvm::cl::list<std::string>
3397 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3400static llvm::cl::opt<std::string>
3402 llvm::cl::desc(
"<output dictionary file>"),
3434 using namespace clang::diag;
3441 const clang::Module *
module = nullptr;
3444 const auto &ID =
Info.getID();
3447 module = fMap.findModule(moduleName);
3453 "Couldn't find module %s in the available modulemaps. This"
3454 "prevents us from correctly diagnosing wrongly built modules.\n",
3485 "Building module '%s' implicitly. If '%s' requires a \n"
3486 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3487 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3497 DiagnosticConsumer::clear();
3503 DiagnosticConsumer::BeginSourceFile(
LangOpts,
PP);
3509 DiagnosticConsumer::EndSourceFile();
3515 DiagnosticConsumer::finish();
3522#if defined(_WIN32) && defined(_MSC_VER)
3526 const char *
EnablePopups = std::getenv(
"Cling_GuiOnAssert");
3539static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3541static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3552static llvm::cl::opt<VerboseLevel>
3554 llvm::cl::values(
clEnumVal(
v,
"Show errors."),
3563static llvm::cl::opt<bool>
3564gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3567static llvm::cl::opt<bool>
3568gOptReflex(
"reflex", llvm::cl::desc(
"Behave internally like genreflex."),
3570static llvm::cl::opt<bool>
3571gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3574static llvm::cl::opt<std::string>
3576 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3579static llvm::cl::opt<bool>
3581 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3584static llvm::cl::opt<bool>
3585gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3587static llvm::cl::opt<bool>
3588gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3590static llvm::cl::list<std::string>
3592 llvm::cl::desc(
"Generate rootmap file."),
3594static llvm::cl::opt<std::string>
3596 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3598static llvm::cl::opt<bool>
3600 llvm::cl::desc(
"Generate a C++ module."),
3602static llvm::cl::list<std::string>
3604 llvm::cl::desc(
"Specify a C++ modulemap file."),
3607static llvm::cl::opt<bool>
3609 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3611static llvm::cl::opt<bool>
3613 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3615static llvm::cl::opt<bool>
3617 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3619static llvm::cl::opt<bool>
3621 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3623static llvm::cl::opt<bool>
3625 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3626information and another the interactivity support."),
3628static llvm::cl::opt<bool>
3631 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3633static llvm::cl::opt<std::string>
3635 llvm::cl::desc(
"The path to the library of the built dictionary."),
3637static llvm::cl::list<std::string>
3639 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3641static llvm::cl::list<std::string>
3643 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3647static llvm::cl::opt<bool>
3649 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3657static llvm::cl::opt<bool>
3660 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3662static llvm::cl::opt<bool>
3664 llvm::cl::desc(
"Check the selection syntax only."),
3666static llvm::cl::opt<bool>
3668 llvm::cl::desc(
"Fail if there are warnings."),
3670static llvm::cl::opt<bool>
3672 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3674static llvm::cl::opt<std::string>
3676 llvm::cl::desc(
"Specify an isysroot."),
3678 llvm::cl::init(
"-"));
3679static llvm::cl::list<std::string>
3681 llvm::cl::desc(
"Specify an include path."),
3683static llvm::cl::list<std::string>
3685 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3687static llvm::cl::list<std::string>
3689 llvm::cl::desc(
"Specify a system include path."),
3691static llvm::cl::list<std::string>
3693 llvm::cl::desc(
"Specify defined macros."),
3695static llvm::cl::list<std::string>
3697 llvm::cl::desc(
"Specify undefined macros."),
3699static llvm::cl::list<std::string>
3701 llvm::cl::desc(
"Specify compiler diagnostics options."),
3703static llvm::cl::opt<std::string>
3705 llvm::cl::desc(
"Write dependency output to the specified file."),
3708static llvm::cl::list<std::string>
3710 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file | selection xml file>"),
3712static llvm::cl::list<std::string>
3714 llvm::cl::desc(
"Consumes all unrecognized options."),
3717static llvm::cl::SubCommand
3720static llvm::cl::list<std::string>
3722 llvm::cl::desc(
"Consumes options and sends them to cling."),
3751 for (
const std::string &header :
modGen.GetHeaders()) {
3756 clang::ConstSearchDirIterator *
CurDir =
nullptr;
3758 header, clang::SourceLocation(),
3761 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>>(),
3800 clang::HeaderSearch &
headerSearch =
CI->getPreprocessor().getHeaderSearchInfo();
3804 clang::Module *
module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3820 msgStream <<
"after creating module \"" <<
module->Name << "\" ";
3821 if (!
module->PresumedModuleMapFile.empty())
3822 msgStream <<
"using modulemap \"" <<
module->PresumedModuleMapFile << "\" ";
3823 msgStream <<
"the following headers are not part of that module:\n";
3827 msgStream <<
" (already part of module \"" << H[1] <<
"\")";
3843 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3853 [](
const std::array<std::string, 2>&
HdrMod) { return HdrMod[0];});
3891 llvm::PrettyStackTraceProgram
X(
argc,
argv);
3894#if defined(R__WIN32) && !defined(R__WINGCC)
3915 auto &
opts = llvm::cl::getRegisteredOptions();
3918 llvm::cl::desc(
"Alias for -help"),
3919 llvm::cl::aliasopt(*
optHelp));
3921 llvm::cl::desc(
"Alias for -help"),
3922 llvm::cl::aliasopt(*
optHelp));
3924 llvm::cl::ParseCommandLineOptions(
argc,
argv,
"rootcling");
3949 return interp->getDiagnostics().hasFatalErrorOccurred();
3966 llvm::cl::PrintHelpMessage();
3981 if ((fp =
fopen(
filein.c_str(),
"r")) ==
nullptr) {
4009 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4010 llvm::cl::PrintHelpMessage();
4022 std::list<std::string>
diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4028 if (GetErrorIgnoreLevel() >
kWarning)
4030 GetWarningsAreErrors() =
true;
4044 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4080 std::vector<std::string>
pcmArgs;
4094 [&](
const std::string& path){
4095 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4103 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(
etcDir));
4110 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4111#elif defined(R__WIN32)
4112 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4119 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4127 clingArgs.push_back(
"-fmodules-embed-all-files");
4191 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4192 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4193 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4194 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4196 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4197 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4201 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4203 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4205 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4206 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4207 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4208 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4209 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4210 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4211 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4213 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4228 std::cerr <<
"Argument \""<<
clingArg <<
"\" is not a supported cling argument. "
4229 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4237 cling::Interpreter*
interpPtr =
nullptr;
4265 clang::CompilerInstance *
CI =
interp.getCI();
4267 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4268 CI->getSourceManager().setAllFilesAreTransient(
true);
4270 clang::Preprocessor &
PP =
CI->getPreprocessor();
4280 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4291 interp.DumpIncludePath();
4296 interp.printIncludedFiles(llvm::outs());
4297 llvm::outs() <<
"\n\n";
4298 llvm::outs().flush();
4302 =
interp.getCI()->getASTContext().getLangOpts();
4305 using CK = clang::LangOptions::CompatibilityKind;
4306#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
4307 if constexpr (CK::Compatibility != CK::Benign) \
4308 ROOT::TMetaUtils::Info(nullptr, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4309#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description)
4310#include "clang/Basic/LangOptions.def"
4314 interp.getOptions().ErrorOut =
true;
4315 interp.enableRawInput(
true);
4319 if (
DepMod.ends_with(
"_rdict.pcm")) {
4326 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4336 if (
interp.declare(
"#include <cassert>\n"
4337 "#include \"Rtypes.h\"\n"
4338 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4346 if (
interp.declare(
"#include <string>\n"
4347 "#include <RtypesCore.h>\n"
4348 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4444 std::stringstream res;
4445 const char*
delim=
"\n";
4448 std::ostream_iterator<std::string>(res,
delim));
4449 if (
interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4458 clang::PragmaNamespace(
pragma) {}
4459 void HandlePragma(clang::Preprocessor &
PP,
4461 clang::Token &
tok)
override {
4462 PP.DiscardUntilEndOfDirective();
4546 if (
dh != std::string::npos) {
4610 if (file.is_open()) {
4642 if (file.is_open()) {
4669 ROOT::TMetaUtils::Error(
nullptr,
"No selection rules specified and creation of C++ module not requested: did you forget to specify a selection file or to request the creation of a C++ module?\n");
4689 <<
"#include \"TVirtualObject.h\"\n"
4690 <<
"#include <vector>\n"
4691 <<
"#include \"TSchemaHelper.h\"\n\n";
4693 std::list<std::string> includes;
4695 for (
auto &
incFile : includes) {
4731 scan.
Scan(
CI->getASTContext());
4754 if (
annRcd.RequestNoInputOperator()) {
4917 [](
const std::string &
a,
const std::string &
b) -> std::string {
4918 if (a.empty()) return b;
4919 else return a +
" " + b;
4949 std::list<std::string>
nsNames;
4992 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4993 CI->getSema().getASTConsumer().HandleTranslationUnit(
CI->getSema().getASTContext());
5010 "rootcling: failed to open dependency file %s\n",
5018 std::replace(path.begin(), path.end(),
'\\',
'/');
5021 for (
char c : path) {
5022 if (
c ==
' ' ||
c ==
'\t' ||
c ==
'#' ||
c ==
':')
5036 clang::SourceManager &
SM =
CI->getSourceManager();
5037 clang::FileManager &
FM =
SM.getFileManager();
5039 llvm::SmallVector<clang::OptionalFileEntryRef, 64>
files;
5070 llvm::sys::fs::make_absolute(
absPath);
5071 if (!llvm::sys::fs::exists(
absPath))
5121 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5135 for (
int i = 1; i <
argc; ++i) {
5138 args.push_back(
argv[i]);
5148 std::cout <<
"Args: \n";
5149 for (std::vector<std::string>::iterator it = args.begin();
5150 it < args.end(); ++it) {
5151 std::cout << i <<
") " << *it << std::endl;
5165 if (std::string::npos !=
result) {
5177 const unsigned int size(str.size());
5178 char *
a =
new char[
size + 1];
5212 const std::string &
optName =
"")
5224 const std::string &
optName =
"")
5241 const std::vector<std::string> &
pcmsNames,
5242 const std::vector<std::string> &includes,
5245 const std::vector<std::string> &
warnings,
5283 "*** genreflex: No rootmap lib and several header specified!\n");
5376 for (
int i = 0; i <
argc; i++) {
5382 std::cout <<
cmd << std::endl;
5391 for (
int i = 0; i <
argc; i++)
5406 const std::vector<std::string> &
pcmsNames,
5407 const std::vector<std::string> &includes,
5410 const std::vector<std::string> &
warnings,
5435 for (
unsigned int i = 0; i <
headersNames.size(); ++i) {
5477 std::vector<std::string> &values)
5482 values.reserve(
nVals);
5484 for (ROOT::option::Option *opt = options[
oIndex]; opt; opt = opt->next()) {
5487 << opt->arg << std::endl;
5489 values.push_back(opt->arg);
5500 const char *descriptor)
5504 "*** genereflex: %s is not supported anymore.\n",
5597 "********************************************************************************\n"
5598 "* The genreflex utility does not allow to generate C++ modules containing *\n"
5599 "* reflection information required at runtime. Please use rootcling instead *\n"
5600 "* To print the rootcling invocation that corresponds to the current genreflex *\n"
5601 "* invocation please use the --print-rootcling-invocation flag. *\n"
5602 "********************************************************************************\n"
5604 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5605 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5609 "--print-rootcling-invocation\n"
5610 " Print to screen the rootcling invocation corresponding to the current \n"
5611 " genreflex invocation.\n";
5614 "-s, --selection_file\tSelection filename\n"
5615 " Class selection file to specify for which classes the dictionary\n"
5616 " will be generated. The final set can be crafted with exclusion and\n"
5617 " exclusion rules.\n"
5618 " Properties can be specified. Some have special meaning:\n"
5619 " - name [string] name of the entity to select with an exact matching\n"
5620 " - pattern [string] name with wildcards (*) to select entities\n"
5621 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5622 " file where the C++ entities reside and not to C++ entities themselves.\n"
5623 " - transient/persistent [string: true/false] The fields to which they are\n"
5624 " applied will not be persistified if requested.\n"
5625 " - comment [string]: what you could write in code after an inline comment\n"
5626 " without \"//\". For example comment=\"!\" or \"||\".\n"
5627 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5628 " Default value is 'false'\n"
5629 " - rntupleStreamerMode [true/false]: enforce streamed or native writing for RNTuple.\n"
5630 " If unset, RNTuple stores classes in split mode or fails if the class cannot be split.\n"
5631 " - rntupleSoARecord [class name]: marks the class as an RNTuple SoA layout for the underlying record\n"
5632 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5633 " to 'true'. Default value is 'false'\n"
5637 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5638 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5639 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5640 " [noInputOperator=\"true/false\"]\n"
5641 " [rntupleStreamerMode=\"true/false\"] />\n"
5642 " [rntupleSoARecord=\"class_name\"] />\n"
5643 " <class name=\"classname\" >\n"
5644 " <field name=\"m_transient\" transient=\"true\"/>\n"
5645 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5646 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5647 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5649 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5650 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5651 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5654 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5655 " <method name=\"unwanted\" />\n"
5660 " If no selection file is specified, the class with the filename without\n"
5661 " extension will be selected, i.e. myClass.h as argument without any\n"
5662 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5665 "-o, --output\tOutput filename\n"
5666 " Output file name. If an existing directory is specified instead of a file,\n"
5667 " then a filename will be built using the name of the input file and will\n"
5668 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5669 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5670 " have unique names.\n";
5674 "-l, --library\tTarget library\n"
5675 " The flag -l must be followed by the name of the library that will\n"
5676 " contain the object file corresponding to the dictionary produced by\n"
5677 " this invocation of genreflex.\n"
5678 " The name takes priority over the one specified for the rootmapfile.\n"
5679 " The name influences the name of the created pcm:\n"
5680 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5681 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5682 " Any \"liblib\" occurrence is transformed in the expected \"lib\".\n"
5683 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5684 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5687 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5688 " This file lists the autoload keys. For example classes for which the\n"
5689 " reflection information is provided.\n"
5690 " The format of the rootmap is the following:\n"
5691 " - Forward declarations section\n"
5692 " - Libraries sections\n"
5693 " Rootmaps can be concatenated together, for example with the cat util.\n"
5694 " In order for ROOT to pick up the information in the rootmaps, they\n"
5695 " have to be located in the library path and have the .rootmap extension.\n"
5696 " An example rootmap file could be:\n"
5698 " template <class T> class A;\n"
5699 " [ libMyLib.so ]\n"
5700 " class A<double>\n"
5706 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5715 ROOT::option::Arg::None,
5722 "",
"print-rootcling-invocation",
5723 ROOT::option::Arg::None,
5731 ROOT::option::FullArg::Required,
5739 ROOT::option::FullArg::Required,
5747 ROOT::option::FullArg::None,
5748 "--multiDict\tSupport for many dictionaries in one library\n"
5749 " Form correct pcm names if multiple dictionaries will be in the same\n"
5750 " library (needs target library switch. See its documentation).\n"
5757 "" ,
"noGlobalUsingStd" ,
5758 ROOT::option::FullArg::None,
5759 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5760 " All header files must have sumbols from std:: namespace fully qualified\n"
5766 "s" ,
"selection_file" ,
5767 ROOT::option::FullArg::Required,
5775 ROOT::option::FullArg::Required,
5782 "" ,
"rootmap-lib" ,
5783 ROOT::option::FullArg::Required,
5790 "" ,
"interpreteronly",
5791 ROOT::option::Arg::None,
5792 "--interpreteronly\tDo not generate I/O related information.\n"
5793 " Generate minimal dictionary required for interactivity.\n"
5800 ROOT::option::Arg::None,
5801 "--split\tSplit the dictionary\n"
5802 " Split in two the dictionary, isolating the part with\n"
5803 " ClassDef related functions in a separate file.\n"
5810 ROOT::option::FullArg::Required,
5811 "-m \tPcm file loaded before any header (option can be repeated).\n"
5818 ROOT::option::Arg::None,
5819 "-v, --verbose\tPrint some debug information.\n"
5826 ROOT::option::Arg::None,
5827 "--debug\tPrint all debug information.\n"
5834 ROOT::option::Arg::None,
5835 "--quiet\tPrint only warnings and errors (default).\n"
5842 ROOT::option::Arg::None,
5843 "--silent\tPrint no information at all.\n"
5849 "" ,
"writeEmptyPCM",
5850 ROOT::option::Arg::None,
5851 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5858 ROOT::option::Arg::None,
5859 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5867 ROOT::option::Arg::None,
5868 "--help\tPrint usage and exit.\n"
5874 "",
"fail_on_warnings",
5875 ROOT::option::Arg::None,
5876 "--fail_on_warnings\tFail on warnings and errors.\n"
5882 "",
"selSyntaxOnly",
5883 ROOT::option::Arg::None,
5884 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5890 "" ,
"noIncludePaths",
5891 ROOT::option::Arg::None,
5892 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5900 ROOT::option::FullArg::Required,
5908 ROOT::option::FullArg::Required,
5916 ROOT::option::FullArg::Required,
5924 ROOT::option::FullArg::Required,
5931 "" ,
"no_membertypedefs" ,
5932 ROOT::option::FullArg::None,
5939 "" ,
"no_templatetypedefs" ,
5940 ROOT::option::FullArg::None,
5944 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
5958 std::vector<ROOT::option::Option> options(stats.options_max);
5959 std::vector<ROOT::option::Option> buffer(stats.buffer_max);
5965 if (
parse.error()) {
6001 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
6026 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6046 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6099 std::vector<std::string> includes;
6198 if (std::string::npos !=
exeName.find(
"genreflex"))
6206 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...
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
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)
@ 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))
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.
static llvm::cl::opt< std::string > gOptDepFile("MF", llvm::cl::desc("Write dependency output to the specified file."), llvm::cl::cat(gRootclingOptions))
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.