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"
108#include "OptionParser.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;
1196 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1202 <<
" // Function generating the singleton type initializer" << std::endl
1204 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1205 <<
" {" << std::endl
1207 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1209 <<
" instance(\"" << classname.c_str() <<
"\", ";
1212 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1218 for (
unsigned int i = 0; i <
filename.length(); i++) {
1222 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1226 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1233 <<
" return &instance;" << std::endl
1234 <<
" }" << std::endl
1235 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1236 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1237 <<
" // Static variable to force the class initialization" << std::endl
1239 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1240 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1243 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1244 <<
" static TClass *" <<
mappedname.c_str() <<
"_Dictionary() {" << std::endl
1245 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1246 <<
" }" << std::endl << std::endl;
1265 llvm::StringRef
where;
1275 errorstring =
"has not been defined before the array";
1278 errorstring =
"is a private member of a parent class";
1287 if (
where.size() == 0) {
1289 member.getParent()->getName().str().c_str(),
member.getName().str().c_str());
1301 const cling::Interpreter &
interp,
1305 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1306 if (
clxx ==
nullptr)
return;
1319 dictStream <<
"//_______________________________________"
1320 <<
"_______________________________________" << std::endl;
1322 dictStream <<
"void " <<
clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1323 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1332 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1341 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1343 <<
" baseClass" <<
basestreamer <<
"::Streamer(R__b);" << std::endl;
1351 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1352 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1363 string classname = fullname;
1364 if (
strstr(fullname.c_str(),
"::")) {
1366 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1367 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1368 classname =
"thisClass";
1370 for (
int i = 0; i < 2; i++) {
1375 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1376 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1377 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1379 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1381 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1386 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1395 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1396 <<
" typedef " <<
base_fullname <<
" baseClass" << base <<
";" << std::endl
1397 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1406 for (clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
1412 std::string
type_name =
type.getAsString(
clxx->getASTContext().getPrintingPolicy());
1429 if (
strncmp(comment,
"!", 1)) {
1433 if (
type.getTypePtr()->isConstantArrayType() &&
1434 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1435 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1442 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1444 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());
1447 dictStream <<
" ;//R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1449 }
else if (
type.getTypePtr()->isPointerType()) {
1453 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1456 dictStream <<
" //R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1465 <<
"," <<
indexvar.str() <<
");" << std::endl;
1468 <<
"," <<
indexvar.str() <<
");" << std::endl;
1471 <<
"," <<
indexvar.str() <<
");" << std::endl;
1478 dictStream <<
" R__b.WriteFastArrayDouble32("
1486 }
else if (
type.getTypePtr()->isArrayType()) {
1488 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1490 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1494 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1497 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1500 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1505 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1508 dictStream <<
" R__b.ReadStaticArrayFloat16(" <<
field_iter->getName().str() <<
");" << std::endl;
1510 dictStream <<
" R__b.ReadStaticArrayDouble32(" <<
field_iter->getName().str() <<
");" << std::endl;
1513 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1518 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1521 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1524 << s <<
");" << std::endl;
1527 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1530 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1533 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1537 dictStream <<
" R__b.WriteArray((Int_t*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1539 dictStream <<
" R__b.WriteArrayFloat16(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1541 dictStream <<
" R__b.WriteArrayDouble32(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1543 dictStream <<
" R__b.WriteArray(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1550 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" <<
field_iter->getName().str() <<
");" << std::endl;
1557 <<
"=Float16_t(R_Dummy);}" << std::endl;
1563 <<
"=Double32_t(R_Dummy);}" << std::endl;
1585 if (
type.getTypePtr()->isConstantArrayType() &&
1586 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1587 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1594 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1605 }
else if (
type.getTypePtr()->isPointerType()) {
1613 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1640 }
else if (
const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1647 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1651 const char *
constwd =
"const ";
1656 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1660 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1667 <<
field_iter->getName().str() <<
"));" << std::endl;
1678 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1679 <<
" }" << std::endl
1680 <<
"}" << std::endl << std::endl;
1691 const cling::Interpreter &
interp,
1697 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1698 if (
clxx ==
nullptr)
return;
1703 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1721 dictStream <<
"//_______________________________________"
1722 <<
"_______________________________________" << std::endl;
1726 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1727 <<
" if (R__b.IsReading()) {" << std::endl
1728 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1729 <<
" } else {" << std::endl
1730 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1731 <<
" }" << std::endl
1732 <<
"}" << std::endl << std::endl;
1743 const cling::Interpreter &
interp,
1782 for (
size_t i = 0; i <
nPaths; i += 1 ) {
1831 cling::Interpreter &
interp,
1834 std::ostringstream out;
1838 modGen.WriteUmbrellaHeader(out);
1839 if (
interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1847 modGen.WriteContentHeader(out);
1860 clang::Module *
module =
nullptr)
1863 llvm::SmallVector<char, 128> buffer;
1864 llvm::BitstreamWriter stream(buffer);
1866 std::unique_ptr<llvm::raw_ostream> out =
1881 out->write(&buffer.front(), buffer.size());
1895 assert(
modGen.IsPCH() &&
"modGen must be in PCH mode");
1897 std::string
iSysRoot(
"/DUMMY_SYSROOT/include/");
1912 std::stringstream includes;
1913 for (
const std::string &header :
headers) {
1914 includes <<
"#include \"" << header <<
"\"\n";
1918 return result == cling::Interpreter::CompilationResult::kSuccess;
1927#ifdef __INTEL_COMPILER
1940#ifdef __GNUC_MINOR__
1956#ifdef _STLPORT_VERSION
1995#if defined(_WIN64) && defined(_DEBUG)
2007 return llvm::sys::path::filename(path).str();
2017 if (std::string::npos != pos) {
2018 dirname.assign(path.begin(), path.begin() + pos + 1);
2086 const cling::Interpreter &
interp)
2088 if (!
decls.empty()) {
2095 names.push_back(
d->getQualifiedNameAsString());
2116 const std::list<std::string> &
nsNames,
2117 const std::list<std::string> &
tdNames,
2118 const std::list<std::string> &
enNames,
2119 const std::list<std::string> &
varNames,
2153 rootmapFile <<
"class " << className << std::endl;
2160 if (className.find(
"<") != std::string::npos)
continue;
2164 auto &header =
headers.front();
2185 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2194 rootmapFile <<
"# List of selected enums and outer classes\n";
2221 if (
foundNsPos == std::string::npos)
return {
"",
""};
2277 std::list<std::string> &
el_list,
2278 std::unordered_set<std::string> &
el_set)
2336 std::cerr <<
"FATAL: A class with normalized name " <<
normalizedName
2337 <<
" was already selected. This means that two different instances of"
2338 <<
" clang::RecordDecl had the same name, which is not possible."
2339 <<
" This can be a hint of a serious problem in the class selection."
2340 <<
" In addition, the generated dictionary would not even compile.\n";
2354 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl)) {
2396 !llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl) &&
2450 if (clang::CXXRecordDecl *
CXXRD =
2451 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2463 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2466 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2469 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2485 if (
interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2486 "#include \"TFile.h\"\n"
2487 "#include \"TObjArray.h\"\n"
2488 "#include \"TVirtualArray.h\"\n"
2489 "#include \"TStreamerElement.h\"\n"
2490 "#include \"TProtoClass.h\"\n"
2491 "#include \"TBaseClass.h\"\n"
2492 "#include \"TListOfDataMembers.h\"\n"
2493 "#include \"TListOfEnums.h\"\n"
2494 "#include \"TListOfEnumsWithLock.h\"\n"
2495 "#include \"TDataMember.h\"\n"
2496 "#include \"TEnum.h\"\n"
2497 "#include \"TEnumConstant.h\"\n"
2498 "#include \"TDictAttributeMap.h\"\n"
2499 "#include \"TMessageHandler.h\"\n"
2500 "#include \"TArray.h\"\n"
2501 "#include \"TRefArray.h\"\n"
2502 "#include \"root_std_complex.h\"\n")
2503 != cling::Interpreter::kSuccess)
2539 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2540 if (
nsName.find(
"(anonymous)") == std::string::npos)
2545 if (!
selClass.GetRecordDecl()->isCompleteDefinition()) {
2549 if (
selClass.RequestOnlyTClass()) {
2557 if (clang::CXXRecordDecl *
CXXRD =
2558 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2562 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2570 }
else if (
CRD->getName() ==
"RVec") {
2571 static const clang::DeclContext *
vecOpsDC =
nullptr;
2573 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2574 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2596 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2600 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2612 if (!
selClass.GetRecordDecl()->isCompleteDefinition() || !
selClass.RequestOnlyTClass()) {
2616 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2662 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2663 <<
"#define R__DICTIONARY_FILENAME " <<
main_dictname << std::endl
2666 <<
"#define R__NO_DEPRECATION" << std::endl
2671 <<
"\n/*******************************************************************/\n"
2672 <<
"#include <cstddef>\n"
2673 <<
"#include <cstdio>\n"
2674 <<
"#include <cstdlib>\n"
2675 <<
"#include <cstring>\n"
2676 <<
"#include <cassert>\n"
2677 <<
"#define G__DICTIONARY\n"
2678 <<
"#include \"ROOT/RConfig.hxx\"\n"
2679 <<
"#include \"TClass.h\"\n"
2680 <<
"#include \"TDictAttributeMap.h\"\n"
2681 <<
"#include \"TInterpreter.h\"\n"
2682 <<
"#include \"TROOT.h\"\n"
2683 <<
"#include \"TBuffer.h\"\n"
2684 <<
"#include \"TMemberInspector.h\"\n"
2685 <<
"#include \"TInterpreter.h\"\n"
2686 <<
"#include \"TVirtualMutex.h\"\n"
2687 <<
"#include \"TError.h\"\n\n"
2688 <<
"#ifndef G__ROOT\n"
2689 <<
"#define G__ROOT\n"
2691 <<
"#include \"RtypesImp.h\"\n"
2692 <<
"#include \"TIsAProxy.h\"\n"
2693 <<
"#include \"TFileMergeInfo.h\"\n"
2694 <<
"#include <algorithm>\n"
2695 <<
"#include \"TCollectionProxyInfo.h\"\n"
2696 <<
"/*******************************************************************/\n\n"
2697 <<
"#include \"TDataMember.h\"\n\n";
2704 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2705 <<
"namespace std {} using namespace std;\n\n";
2714 dictStream <<
"// Header files passed as explicit arguments\n"
2716 <<
"// Header files passed via #pragma extra_include\n"
2723#if defined(R__IOSSIM) || defined(R__IOS)
2784 for (
unsigned int i = 0; i <
m_size; ++i) {
2792 if (
ifile.is_open())
2794 if (0 != std::remove(
tmpName)) {
2807 for (
unsigned int i = 0; i <
m_size; ++i) {
2816 if (
ifile.is_open())
2824 llvm::sys::fs::remove(
tmpName);
2849 std::cout <<
"Restoring files in temporary file catalog:\n";
2850 for (
unsigned int i = 0; i <
m_size; ++i) {
2883 static const std::string pattern(
"-Wno-");
2885 if (arg.find(pattern) != 0)
2896 cling::Interpreter &
interp)
2921 if (
qt.isNull())
return qt;
2923 while (
thisQt->isPointerType() ||
2924 thisQt->isReferenceType()) {
2935 const cling::Interpreter &
interp,
2938 std::list<std::string>
headers;
2941 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
2948 if (
const clang::ClassTemplateSpecializationDecl *
tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&
rcd)) {
2951 for (
auto &
tArg :
tsd->getTemplateArgs().asArray()) {
2952 if (clang::TemplateArgument::ArgKind::Type !=
tArg.getKind())
continue;
2973 if (
const clang::FieldDecl *
fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*
declIt)) {
2986 for (
auto & fPar :
methodIt->parameters()) {
3021 if (!
dclCtxt->isStdNamespace()){
3041 if (
argKind != clang::TemplateArgument::Type){
3042 if (
argKind == clang::TemplateArgument::Integral)
continue;
3049 if (
isPOD)
continue;
3074 const cling::Interpreter &
interp)
3077 std::unordered_set<std::string> buffer;
3082 if (
const clang::CXXRecordDecl *
cxxRcd =
3083 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
annotatedRcd.GetRecordDecl())) {
3089 headers.remove_if([&buffer](
const std::string & s) {
3090 return !buffer.insert(s).second;
3103 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(
cxxRcd)){
3112 if (clang::CXXRecordDecl *
cxxRcd =
tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3119 headers.remove_if([&buffer](
const std::string & s) {
3120 return !buffer.insert(s).second;
3151 const cling::Interpreter &
interp)
3159 std::unordered_set<std::string>
fwdDecls;
3202 std::cout <<
"Logs from forward decl printer: \n"
3233 std::cout <<
"Class-headers Mapping:\n";
3249 std::cout << std::endl;
3276 static const std::vector<std::string>
namePrfxes {
3281 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3299 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3313 std::cerr <<
"Error: Class " <<
clName <<
" has been selected but "
3314 <<
"currently the support for its I/O is not yet available. Note that "
3315 <<
clName <<
", even if not selected, will be available for "
3316 <<
"interpreted code.\n";
3320 std::cerr <<
"Error: It is not necessary to explicitly select class "
3321 <<
clName <<
". I/O is supported for it transparently.\n";
3336 InterpreterCallbacks(
interp),
3342 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3343 clang::OptionalFileEntryRef , llvm::StringRef ,
3344 llvm::StringRef ,
const clang::Module * ,
bool ,
3345 clang::SrcMgr::CharacteristicKind )
override
3380 using namespace clang;
3381 if (llvm::StringRef(M->Name).ends_with(
"ACLiC_dict")) {
3387 assert(M &&
"Must have module Core");
3394 llvm::cl::desc(
"Allow implicit build of system modules."),
3396static llvm::cl::list<std::string>
3399 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3402static llvm::cl::opt<std::string>
3404 llvm::cl::desc(
"<output dictionary file>"),
3436 using namespace clang::diag;
3443 const clang::Module *
module = nullptr;
3446 const auto &ID =
Info.getID();
3449 module = fMap.findModule(moduleName);
3455 "Couldn't find module %s in the available modulemaps. This"
3456 "prevents us from correctly diagnosing wrongly built modules.\n",
3487 "Building module '%s' implicitly. If '%s' requires a \n"
3488 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3489 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3499 DiagnosticConsumer::clear();
3505 DiagnosticConsumer::BeginSourceFile(
LangOpts,
PP);
3511 DiagnosticConsumer::EndSourceFile();
3517 DiagnosticConsumer::finish();
3524#if defined(_WIN32) && defined(_MSC_VER)
3528 const char *
EnablePopups = std::getenv(
"Cling_GuiOnAssert");
3541static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3543static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3554static llvm::cl::opt<VerboseLevel>
3556 llvm::cl::values(
clEnumVal(
v,
"Show errors."),
3565static llvm::cl::opt<bool>
3566gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3569static llvm::cl::opt<bool>
3570gOptReflex(
"reflex", llvm::cl::desc(
"Behave internally like genreflex."),
3572static llvm::cl::opt<bool>
3573gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3576static llvm::cl::opt<std::string>
3578 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3581static llvm::cl::opt<bool>
3583 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3586static llvm::cl::opt<bool>
3587gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3589static llvm::cl::opt<bool>
3590gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3592static llvm::cl::list<std::string>
3594 llvm::cl::desc(
"Generate rootmap file."),
3596static llvm::cl::opt<std::string>
3598 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3600static llvm::cl::opt<bool>
3602 llvm::cl::desc(
"Generate a C++ module."),
3604static llvm::cl::list<std::string>
3606 llvm::cl::desc(
"Specify a C++ modulemap file."),
3609static llvm::cl::opt<bool>
3611 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3613static llvm::cl::opt<bool>
3615 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3617static llvm::cl::opt<bool>
3619 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3621static llvm::cl::opt<bool>
3623 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3625static llvm::cl::opt<bool>
3627 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3628information and another the interactivity support."),
3630static llvm::cl::opt<bool>
3633 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3635static llvm::cl::opt<std::string>
3637 llvm::cl::desc(
"The path to the library of the built dictionary."),
3639static llvm::cl::list<std::string>
3641 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3643static llvm::cl::list<std::string>
3645 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3649static llvm::cl::opt<bool>
3651 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3659static llvm::cl::opt<bool>
3662 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3664static llvm::cl::opt<bool>
3666 llvm::cl::desc(
"Check the selection syntax only."),
3668static llvm::cl::opt<bool>
3670 llvm::cl::desc(
"Fail if there are warnings."),
3672static llvm::cl::opt<bool>
3674 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3676static llvm::cl::opt<std::string>
3678 llvm::cl::desc(
"Specify an isysroot."),
3680 llvm::cl::init(
"-"));
3681static llvm::cl::list<std::string>
3683 llvm::cl::desc(
"Specify an include path."),
3685static llvm::cl::list<std::string>
3687 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3689static llvm::cl::list<std::string>
3691 llvm::cl::desc(
"Specify a system include path."),
3693static llvm::cl::list<std::string>
3695 llvm::cl::desc(
"Specify defined macros."),
3697static llvm::cl::list<std::string>
3699 llvm::cl::desc(
"Specify undefined macros."),
3701static llvm::cl::list<std::string>
3703 llvm::cl::desc(
"Specify compiler diagnostics options."),
3705static llvm::cl::opt<std::string>
3707 llvm::cl::desc(
"Write dependency output to the specified file."),
3710static llvm::cl::list<std::string>
3712 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file | selection xml file>"),
3714static llvm::cl::list<std::string>
3716 llvm::cl::desc(
"Consumes all unrecognized options."),
3719static llvm::cl::SubCommand
3722static llvm::cl::list<std::string>
3724 llvm::cl::desc(
"Consumes options and sends them to cling."),
3753 for (
const std::string &header :
modGen.GetHeaders()) {
3758 clang::ConstSearchDirIterator *
CurDir =
nullptr;
3760 header, clang::SourceLocation(),
3763 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>>(),
3802 clang::HeaderSearch &
headerSearch =
CI->getPreprocessor().getHeaderSearchInfo();
3806 clang::Module *
module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3822 msgStream <<
"after creating module \"" <<
module->Name << "\" ";
3823 if (!
module->PresumedModuleMapFile.empty())
3824 msgStream <<
"using modulemap \"" <<
module->PresumedModuleMapFile << "\" ";
3825 msgStream <<
"the following headers are not part of that module:\n";
3829 msgStream <<
" (already part of module \"" << H[1] <<
"\")";
3845 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3855 [](
const std::array<std::string, 2>&
HdrMod) { return HdrMod[0];});
3893 llvm::PrettyStackTraceProgram
X(
argc,
argv);
3896#if defined(R__WIN32) && !defined(R__WINGCC)
3917 auto &
opts = llvm::cl::getRegisteredOptions();
3920 llvm::cl::desc(
"Alias for -help"),
3921 llvm::cl::aliasopt(*
optHelp));
3923 llvm::cl::desc(
"Alias for -help"),
3924 llvm::cl::aliasopt(*
optHelp));
3926 llvm::cl::ParseCommandLineOptions(
argc,
argv,
"rootcling");
3951 return interp->getDiagnostics().hasFatalErrorOccurred();
3968 llvm::cl::PrintHelpMessage();
3983 if ((fp =
fopen(
filein.c_str(),
"r")) ==
nullptr) {
4011 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4012 llvm::cl::PrintHelpMessage();
4024 std::list<std::string>
diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4030 if (GetErrorIgnoreLevel() >
kWarning)
4032 GetWarningsAreErrors() =
true;
4046 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4082 std::vector<std::string>
pcmArgs;
4096 [&](
const std::string& path){
4097 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4105 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(
etcDir));
4112 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4113#elif defined(R__WIN32)
4114 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4121 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4129 clingArgs.push_back(
"-fmodules-embed-all-files");
4193 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4194 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4195 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4196 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4198 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4199 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4203 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4205 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4207 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4208 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4209 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4210 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4211 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4212 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4213 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4215 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4230 std::cerr <<
"Argument \""<<
clingArg <<
"\" is not a supported cling argument. "
4231 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4239 cling::Interpreter*
interpPtr =
nullptr;
4267 clang::CompilerInstance *
CI =
interp.getCI();
4269 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4270 CI->getSourceManager().setAllFilesAreTransient(
true);
4272 clang::Preprocessor &
PP =
CI->getPreprocessor();
4282 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4293 interp.DumpIncludePath();
4298 interp.printIncludedFiles(llvm::outs());
4299 llvm::outs() <<
"\n\n";
4300 llvm::outs().flush();
4304 =
interp.getCI()->getASTContext().getLangOpts();
4307 using CK = clang::LangOptions::CompatibilityKind;
4308#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
4309 if constexpr (CK::Compatibility != CK::Benign) \
4310 ROOT::TMetaUtils::Info(nullptr, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4311#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description)
4312#include "clang/Basic/LangOptions.def"
4316 interp.getOptions().ErrorOut =
true;
4317 interp.enableRawInput(
true);
4321 if (
DepMod.ends_with(
"_rdict.pcm")) {
4328 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4338 if (
interp.declare(
"#include <cassert>\n"
4339 "#include \"Rtypes.h\"\n"
4340 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4348 if (
interp.declare(
"#include <string>\n"
4349 "#include <RtypesCore.h>\n"
4350 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4446 std::stringstream res;
4447 const char*
delim=
"\n";
4450 std::ostream_iterator<std::string>(res,
delim));
4451 if (
interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4460 clang::PragmaNamespace(
pragma) {}
4461 void HandlePragma(clang::Preprocessor &
PP,
4463 clang::Token &
tok)
override {
4464 PP.DiscardUntilEndOfDirective();
4548 if (
dh != std::string::npos) {
4612 if (file.is_open()) {
4644 if (file.is_open()) {
4671 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");
4691 <<
"#include \"TVirtualObject.h\"\n"
4692 <<
"#include <vector>\n"
4693 <<
"#include \"TSchemaHelper.h\"\n\n";
4695 std::list<std::string> includes;
4697 for (
auto &
incFile : includes) {
4733 scan.
Scan(
CI->getASTContext());
4756 if (
annRcd.RequestNoInputOperator()) {
4919 [](
const std::string &
a,
const std::string &
b) -> std::string {
4920 if (a.empty()) return b;
4921 else return a +
" " + b;
4951 std::list<std::string>
nsNames;
4994 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4995 CI->getSema().getASTConsumer().HandleTranslationUnit(
CI->getSema().getASTContext());
5012 "rootcling: failed to open dependency file %s\n",
5020 std::replace(path.begin(), path.end(),
'\\',
'/');
5023 for (
char c : path) {
5024 if (
c ==
' ' ||
c ==
'\t' ||
c ==
'#' ||
c ==
':')
5038 clang::SourceManager &
SM =
CI->getSourceManager();
5039 clang::FileManager &
FM =
SM.getFileManager();
5041 llvm::SmallVector<clang::OptionalFileEntryRef, 64>
files;
5072 llvm::sys::fs::make_absolute(
absPath);
5073 if (!llvm::sys::fs::exists(
absPath))
5123 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5137 for (
int i = 1; i <
argc; ++i) {
5140 args.push_back(
argv[i]);
5150 std::cout <<
"Args: \n";
5151 for (std::vector<std::string>::iterator it = args.begin();
5152 it < args.end(); ++it) {
5153 std::cout << i <<
") " << *it << std::endl;
5167 if (std::string::npos !=
result) {
5179 const unsigned int size(str.size());
5180 char *
a =
new char[
size + 1];
5214 const std::string &
optName =
"")
5226 const std::string &
optName =
"")
5243 const std::vector<std::string> &
pcmsNames,
5244 const std::vector<std::string> &includes,
5247 const std::vector<std::string> &
warnings,
5285 "*** genreflex: No rootmap lib and several header specified!\n");
5378 for (
int i = 0; i <
argc; i++) {
5384 std::cout <<
cmd << std::endl;
5393 for (
int i = 0; i <
argc; i++)
5408 const std::vector<std::string> &
pcmsNames,
5409 const std::vector<std::string> &includes,
5412 const std::vector<std::string> &
warnings,
5437 for (
unsigned int i = 0; i <
headersNames.size(); ++i) {
5479 std::vector<std::string> &values)
5484 values.reserve(
nVals);
5486 for (ROOT::option::Option *opt = options[
oIndex]; opt; opt = opt->next()) {
5489 << opt->arg << std::endl;
5491 values.push_back(opt->arg);
5502 const char *descriptor)
5506 "*** genereflex: %s is not supported anymore.\n",
5599 "********************************************************************************\n"
5600 "* The genreflex utility does not allow to generate C++ modules containing *\n"
5601 "* reflection information required at runtime. Please use rootcling instead *\n"
5602 "* To print the rootcling invocation that corresponds to the current genreflex *\n"
5603 "* invocation please use the --print-rootcling-invocation flag. *\n"
5604 "********************************************************************************\n"
5606 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5607 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5611 "--print-rootcling-invocation\n"
5612 " Print to screen the rootcling invocation corresponding to the current \n"
5613 " genreflex invocation.\n";
5616 "-s, --selection_file\tSelection filename\n"
5617 " Class selection file to specify for which classes the dictionary\n"
5618 " will be generated. The final set can be crafted with exclusion and\n"
5619 " exclusion rules.\n"
5620 " Properties can be specified. Some have special meaning:\n"
5621 " - name [string] name of the entity to select with an exact matching\n"
5622 " - pattern [string] name with wildcards (*) to select entities\n"
5623 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5624 " file where the C++ entities reside and not to C++ entities themselves.\n"
5625 " - transient/persistent [string: true/false] The fields to which they are\n"
5626 " applied will not be persistified if requested.\n"
5627 " - comment [string]: what you could write in code after an inline comment\n"
5628 " without \"//\". For example comment=\"!\" or \"||\".\n"
5629 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5630 " Default value is 'false'\n"
5631 " - rntupleStreamerMode [true/false]: enforce streamed or native writing for RNTuple.\n"
5632 " If unset, RNTuple stores classes in split mode or fails if the class cannot be split.\n"
5633 " - rntupleSoARecord [class name]: marks the class as an RNTuple SoA layout for the underlying record\n"
5634 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5635 " to 'true'. Default value is 'false'\n"
5639 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5640 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5641 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5642 " [noInputOperator=\"true/false\"]\n"
5643 " [rntupleStreamerMode=\"true/false\"] />\n"
5644 " [rntupleSoARecord=\"class_name\"] />\n"
5645 " <class name=\"classname\" >\n"
5646 " <field name=\"m_transient\" transient=\"true\"/>\n"
5647 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5648 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5649 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5651 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5652 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5653 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5656 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5657 " <method name=\"unwanted\" />\n"
5662 " If no selection file is specified, the class with the filename without\n"
5663 " extension will be selected, i.e. myClass.h as argument without any\n"
5664 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5667 "-o, --output\tOutput filename\n"
5668 " Output file name. If an existing directory is specified instead of a file,\n"
5669 " then a filename will be built using the name of the input file and will\n"
5670 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5671 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5672 " have unique names.\n";
5676 "-l, --library\tTarget library\n"
5677 " The flag -l must be followed by the name of the library that will\n"
5678 " contain the object file corresponding to the dictionary produced by\n"
5679 " this invocation of genreflex.\n"
5680 " The name takes priority over the one specified for the rootmapfile.\n"
5681 " The name influences the name of the created pcm:\n"
5682 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5683 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5684 " Any \"liblib\" occurrence is transformed in the expected \"lib\".\n"
5685 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5686 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5689 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5690 " This file lists the autoload keys. For example classes for which the\n"
5691 " reflection information is provided.\n"
5692 " The format of the rootmap is the following:\n"
5693 " - Forward declarations section\n"
5694 " - Libraries sections\n"
5695 " Rootmaps can be concatenated together, for example with the cat util.\n"
5696 " In order for ROOT to pick up the information in the rootmaps, they\n"
5697 " have to be located in the library path and have the .rootmap extension.\n"
5698 " An example rootmap file could be:\n"
5700 " template <class T> class A;\n"
5701 " [ libMyLib.so ]\n"
5702 " class A<double>\n"
5708 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5717 ROOT::option::Arg::None,
5724 "",
"print-rootcling-invocation",
5725 ROOT::option::Arg::None,
5733 ROOT::option::FullArg::Required,
5741 ROOT::option::FullArg::Required,
5749 ROOT::option::FullArg::None,
5750 "--multiDict\tSupport for many dictionaries in one library\n"
5751 " Form correct pcm names if multiple dictionaries will be in the same\n"
5752 " library (needs target library switch. See its documentation).\n"
5759 "" ,
"noGlobalUsingStd" ,
5760 ROOT::option::FullArg::None,
5761 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5762 " All header files must have sumbols from std:: namespace fully qualified\n"
5768 "s" ,
"selection_file" ,
5769 ROOT::option::FullArg::Required,
5777 ROOT::option::FullArg::Required,
5784 "" ,
"rootmap-lib" ,
5785 ROOT::option::FullArg::Required,
5792 "" ,
"interpreteronly",
5793 ROOT::option::Arg::None,
5794 "--interpreteronly\tDo not generate I/O related information.\n"
5795 " Generate minimal dictionary required for interactivity.\n"
5802 ROOT::option::Arg::None,
5803 "--split\tSplit the dictionary\n"
5804 " Split in two the dictionary, isolating the part with\n"
5805 " ClassDef related functions in a separate file.\n"
5812 ROOT::option::FullArg::Required,
5813 "-m \tPcm file loaded before any header (option can be repeated).\n"
5820 ROOT::option::Arg::None,
5821 "-v, --verbose\tPrint some debug information.\n"
5828 ROOT::option::Arg::None,
5829 "--debug\tPrint all debug information.\n"
5836 ROOT::option::Arg::None,
5837 "--quiet\tPrint only warnings and errors (default).\n"
5844 ROOT::option::Arg::None,
5845 "--silent\tPrint no information at all.\n"
5851 "" ,
"writeEmptyPCM",
5852 ROOT::option::Arg::None,
5853 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5860 ROOT::option::Arg::None,
5861 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5869 ROOT::option::Arg::None,
5870 "--help\tPrint usage and exit.\n"
5876 "",
"fail_on_warnings",
5877 ROOT::option::Arg::None,
5878 "--fail_on_warnings\tFail on warnings and errors.\n"
5884 "",
"selSyntaxOnly",
5885 ROOT::option::Arg::None,
5886 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5892 "" ,
"noIncludePaths",
5893 ROOT::option::Arg::None,
5894 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5902 ROOT::option::FullArg::Required,
5910 ROOT::option::FullArg::Required,
5918 ROOT::option::FullArg::Required,
5926 ROOT::option::FullArg::Required,
5933 "" ,
"no_membertypedefs" ,
5934 ROOT::option::FullArg::None,
5941 "" ,
"no_templatetypedefs" ,
5942 ROOT::option::FullArg::None,
5946 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
5960 std::vector<ROOT::option::Option> options(stats.options_max);
5961 std::vector<ROOT::option::Option> buffer(stats.buffer_max);
5967 if (
parse.error()) {
6003 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
6028 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6048 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6101 std::vector<std::string> includes;
6200 if (std::string::npos !=
exeName.find(
"genreflex"))
6208 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.