12#include "rootclingCommandLineOptionsHelp.h"
14#include "RConfigure.h"
33#include <unordered_map>
34#include <unordered_set>
46#define PATH_MAX _MAX_PATH
54#include <mach-o/dyld.h>
62#include <libprocstat.h>
71#include "cling/Interpreter/Interpreter.h"
72#include "cling/Interpreter/InterpreterCallbacks.h"
73#include "cling/Interpreter/LookupHelper.h"
74#include "cling/Interpreter/Value.h"
75#include "clang/AST/CXXInheritance.h"
76#include "clang/Basic/Diagnostic.h"
77#include "clang/Frontend/CompilerInstance.h"
78#include "clang/Frontend/FrontendActions.h"
79#include "clang/Frontend/FrontendDiagnostic.h"
80#include "clang/Lex/HeaderSearch.h"
81#include "clang/Lex/Preprocessor.h"
82#include "clang/Lex/ModuleMap.h"
83#include "clang/Lex/Pragma.h"
84#include "clang/Sema/Sema.h"
85#include "clang/Serialization/ASTWriter.h"
86#include "cling/Utils/AST.h"
88#include "llvm/ADT/StringRef.h"
90#include "llvm/Support/CommandLine.h"
91#include "llvm/Support/Path.h"
92#include "llvm/Support/PrettyStackTrace.h"
93#include "llvm/Support/Signals.h"
117#include <mach-o/dyld.h>
122#define strcasecmp _stricmp
123#define strncasecmp _strnicmp
131#define rootclingStringify(s) rootclingStringifyx(s)
132#define rootclingStringifyx(s) #s
139using std::string, std::map, std::ifstream, std::ofstream, std::endl, std::ios, std::vector;
150static llvm::cl::opt<bool>
152 llvm::cl::desc(
"Deprecated. Similar to -f but it ignores the dictionary generation. \
153When -r is present rootcling becomes a tool to generate rootmaps (and capability files)."),
178 gDriverConfig->fAddTypedefToROOTFile(
td->getQualifiedNameAsString().c_str());
186 if (clang::isa<clang::TranslationUnitDecl>(
en->getDeclContext())
187 || clang::isa<clang::LinkageSpecDecl>(
en->getDeclContext())
188 || clang::isa<clang::NamespaceDecl>(
en->getDeclContext()))
189 gDriverConfig->fAddEnumToROOTFile(
en->getQualifiedNameAsString().c_str());
203#if defined(__linux) || defined(__linux__)
212 if (
ret > 0 &&
ret < 1024) {
246 const cling::Interpreter &
interp)
264 clang::ASTContext &C =
decl.getASTContext();
270 if (! it->GetAttributeValue(propNames::name,
varName))
continue;
274 BaseSelectionRule::AttributesMap_t::iterator iter;
277 const std::string &
name = iter->first;
278 const std::string &
value = iter->second;
280 if (
name == propNames::name)
continue;
285 if (
name == propNames::iotype &&
286 (
decl.getType()->isArrayType() ||
decl.getType()->isPointerType())) {
287 const char *
msg =
"Data member \"%s\" is an array or a pointer. "
288 "It is not possible to assign to it the iotype \"%s\". "
289 "This transformation is possible only with data members "
290 "which are not pointers or arrays.\n";
300 if (
name == propNames::comment) {
301 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
value,
nullptr, 0));
305 if ((
name == propNames::transient &&
value ==
"true") ||
306 (
name == propNames::persistent &&
value ==
"false")) {
311 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
"!",
nullptr, 0));
337 using namespace clang;
339 llvm::StringRef comment;
356 BaseSelectionRule::AttributesMap_t::iterator iter;
359 const std::string &
name =
attr.first;
371 for (CXXRecordDecl::decl_iterator
I =
CXXRD.decls_begin(),
372 E =
CXXRD.decls_end();
I != E; ++
I) {
376 if (!(*I)->isImplicit()
388 if (comment.size()) {
391 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
398 (*I)->addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
422 while (
const clang::ConstantArrayType *
subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual())) {
426 return len.getLimitedValue();
432 const cling::Interpreter &
interp)
437 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
444 const cling::Interpreter &
interp)
489 fprintf(
stderr,
"rootcling: error getting realpath of rootcling!");
494 char *
ep =
new char[
nche];
502 if (!
strncmp(s + 1,
"rootcling_stage1.exe", 20)) {
506 }
else if (!
strncmp(s + 1,
"rootcling_stage1", 16)) {
551 size_t *end =
nullptr)
554 if (
line[0] !=
'#')
return false;
579 clang::Module *M =
recordDecl->getOwningModule()->getTopLevelModule();
597 if (classname.find(
':') == std::string::npos)
return;
600 int slen = classname.size();
601 for (
int k = 0; k <
slen; ++k) {
602 if (classname[k] ==
':') {
603 if (k + 1 >=
slen || classname[k + 1] !=
':') {
608 string base = classname.substr(0, k);
617 }
else if (classname[k] ==
'<') {
629 std::string classname;
631 while (file >>
line) {
633 if (
line.find(
"Library.") != 0)
continue;
635 int pos =
line.find(
":", 8);
636 classname =
line.substr(8, pos - 8);
642 while (
line[0] ==
' ')
line.replace(0, 1,
"");
646 if (classname ==
"ROOT::TImpProxy") {
665 const std::unordered_map<char, unsigned int>
keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
668 if (
line ==
"{ decls }") {
670 if (
line[0] ==
'[')
break;
677 while (
libs[0] ==
' ')
libs.replace(0, 1,
"");
701 if (llvm::sys::fs::is_directory(
filename))
continue;
709 file.seekg(0, std::ios::beg);
730 const string &fullname,
731 const clang::RecordDecl *cl,
732 cling::Interpreter &
interp)
735 const clang::FunctionDecl *
method
740 clang::TranslationUnitDecl *
TU =
741 cl->getASTContext().getTranslationUnitDecl();
746 if (
method !=
nullptr && (
method->getAccess() == clang::AS_public ||
method->getAccess() == clang::AS_none)) {
765 "in this version of ROOT, the option '!' used in a linkdef file\n"
766 " implies the actual existence of customized operators.\n"
767 " The following declaration is now required:\n"
782 int ncha = fullname.length() + 13;
807 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
818 "because it inherits from TObject but does not "
819 "have its own ClassDef.\n",
832 if (
m.getType().isConstQualified()) {
833 string ret =
"const_cast< ";
843 ret +=
m.getName().str();
847 return prefix +
m.getName().str();
857 const cling::Interpreter &
interp,
875 if (!
clxx ||
clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
877 const clang::ClassTemplateSpecializationDecl *
tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (
clxx);
885 const char *
tcl1 =
nullptr, *
tcl2 =
nullptr;
887 clang::QualType
ti =
arg0.getAsType();
905 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
911 if (
arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
915 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
917 }
else if (
m.getType()->isPointerType()) {
924 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
936 <<
" *" <<
stlName.c_str() <<
" = new " <<
stlType.c_str() <<
";" << std::endl
937 <<
" " <<
stlType.c_str() <<
" &R__stl = **" <<
stlName.c_str() <<
";" << std::endl;
941 <<
" " <<
stlName.c_str() <<
"[R__l] = new " <<
stlType.c_str() <<
";" << std::endl
942 <<
" " <<
stlType.c_str() <<
" &R__stl = *" <<
stlName.c_str() <<
"[R__l];" << std::endl;
946 dictStream <<
" R__stl.clear();" << std::endl;
949 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
950 <<
" if (R__tcl1==0) {" << std::endl
951 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
952 <<
fulName1.c_str() <<
"!\");" << std::endl
953 <<
" return;" << std::endl
954 <<
" }" << std::endl;
957 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
958 <<
" if (R__tcl2==0) {" << std::endl
959 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
960 <<
fulName2.c_str() <<
"!\");" << std::endl
961 <<
" return;" << std::endl
962 <<
" }" << std::endl;
966 <<
" R__b >> R__n;" << std::endl;
969 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
971 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
997 <<
" std::pair<Value_t const, " <<
tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
998 <<
" R__stl.insert(R__t3);" << std::endl;
1006 dictStream <<
" R__stl.insert(R__t);" << std::endl;
1011 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
1014 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
1020 <<
" }" << std::endl;
1027 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
1045 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
1046 <<
" R__b << R__n;" << std::endl
1047 <<
" if(R__n) {" << std::endl;
1050 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
1051 <<
" if (R__tcl1==0) {" << std::endl
1052 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
1053 <<
fulName1.c_str() <<
"!\");" << std::endl
1054 <<
" return;" << std::endl
1055 <<
" }" << std::endl;
1058 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
1059 <<
" if (R__tcl2==0) {" << std::endl
1060 <<
" Error(\"" <<
stlName.c_str() <<
"streamer\",\"Missing the TClass object for " <<
fulName2.c_str() <<
"!\");" << std::endl
1061 <<
" return;" << std::endl
1062 <<
" }" << std::endl;
1066 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
1077 <<
" }" << std::endl
1078 <<
" }" << std::endl;
1100 if (
m.getType()->isConstantArrayType()) {
1101 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1102 dictStream <<
"// Array of pointer to std::string are not supported (" <<
fieldname <<
"\n";
1105 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1108 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1109 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1110 fullIdx <<
"[R__i" << dim <<
"]";
1111 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1114 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1118 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1119 if (
m.getType()->isPointerType())
1121 <<
fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1127 if (
m.getType()->isPointerType())
1129 <<
fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1130 else if (
m.getType()->isConstantArrayType()) {
1132 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1135 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1136 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1137 fullIdx <<
"[R__i" << dim <<
"]";
1138 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1143 dictStream <<
" { TString R__str = " <<
fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1154 if (
m.getType()->isPointerType()) {
1155 if (
m.getType()->getPointeeType()->isPointerType()) {
1167 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1169 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1172 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1194 dictStream <<
"#include \"TInterpreter.h\"\n";
1196 dictStream <<
"//_______________________________________"
1197 <<
"_______________________________________" << std::endl;
1199 dictStream <<
"atomic_TClass_ptr " <<
clsname <<
"::fgIsA(nullptr); // static to hold class pointer" << std::endl
1202 <<
"//_______________________________________"
1203 <<
"_______________________________________" << std::endl;
1205 dictStream <<
"const char *" <<
clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1206 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1208 dictStream <<
"//_______________________________________"
1209 <<
"_______________________________________" << std::endl;
1211 dictStream <<
"const char *" <<
clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1212 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1213 <<
"*)nullptr)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1215 <<
"//_______________________________________"
1216 <<
"_______________________________________" << std::endl;
1218 dictStream <<
"int " <<
clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1219 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1220 <<
"*)nullptr)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1222 <<
"//_______________________________________"
1223 <<
"_______________________________________" << std::endl;
1225 dictStream <<
"TClass *" <<
clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1229 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1230 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1231 <<
"*)nullptr)->GetClass();" << std::endl
1232 <<
" return fgIsA;\n"
1233 <<
"}" << std::endl << std::endl
1235 <<
"//_______________________________________"
1236 <<
"_______________________________________" << std::endl;
1238 dictStream <<
"TClass *" <<
clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1242 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1243 dictStream << fullname <<
"*)nullptr)->GetClass(); }" << std::endl;
1246 <<
"}" << std::endl << std::endl;
1258 cling::Interpreter &
interp,
1261 if (cl->isAnonymousNamespace()) {
1273 if (classname !=
"ROOT") {
1277 dictStream <<
" namespace ROOTDict {" << std::endl;
1280 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1287 <<
" // Function generating the singleton type initializer" << std::endl
1290 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1291 <<
" {" << std::endl
1293 <<
" ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1294 <<
" {" << std::endl
1297 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1299 <<
" instance(\"" << classname.c_str() <<
"\", ";
1302 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1308 for (
unsigned int i = 0; i <
filename.length(); i++) {
1312 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1316 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1323 <<
" return &instance;" << std::endl
1324 <<
" }" << std::endl
1325 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1326 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1327 <<
" // Static variable to force the class initialization" << std::endl
1329 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1330 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1333 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1334 <<
" static TClass *" <<
mappedname.c_str() <<
"_Dictionary() {" << std::endl
1335 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1336 <<
" }" << std::endl << std::endl;
1355 llvm::StringRef
where;
1358 if (
index.size() == 0 && printError) {
1365 errorstring =
"has not been defined before the array";
1368 errorstring =
"is a private member of a parent class";
1377 if (
where.size() == 0) {
1379 member.getParent()->getName().str().c_str(),
member.getName().str().c_str());
1391 const cling::Interpreter &
interp,
1395 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1396 if (
clxx ==
nullptr)
return;
1409 dictStream <<
"//_______________________________________"
1410 <<
"_______________________________________" << std::endl;
1412 dictStream <<
"void " <<
clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1413 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1422 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1431 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1433 <<
" baseClass" <<
basestreamer <<
"::Streamer(R__b);" << std::endl;
1441 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1442 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1453 string classname = fullname;
1454 if (
strstr(fullname.c_str(),
"::")) {
1456 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1457 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1458 classname =
"thisClass";
1460 for (
int i = 0; i < 2; i++) {
1465 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1466 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1467 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1469 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1471 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1476 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1485 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1486 <<
" typedef " <<
base_fullname <<
" baseClass" << base <<
";" << std::endl
1487 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1496 for (clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
1502 std::string
type_name =
type.getAsString(
clxx->getASTContext().getPrintingPolicy());
1519 if (
strncmp(comment,
"!", 1)) {
1523 if (
type.getTypePtr()->isConstantArrayType() &&
1524 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1525 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1532 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1534 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());
1537 dictStream <<
" ;//R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1539 }
else if (
type.getTypePtr()->isPointerType()) {
1543 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1546 dictStream <<
" //R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1555 <<
"," <<
indexvar.str() <<
");" << std::endl;
1558 <<
"," <<
indexvar.str() <<
");" << std::endl;
1561 <<
"," <<
indexvar.str() <<
");" << std::endl;
1568 dictStream <<
" R__b.WriteFastArrayDouble32("
1576 }
else if (
type.getTypePtr()->isArrayType()) {
1578 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1580 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1584 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1587 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1590 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1595 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1598 dictStream <<
" R__b.ReadStaticArrayFloat16(" <<
field_iter->getName().str() <<
");" << std::endl;
1600 dictStream <<
" R__b.ReadStaticArrayDouble32(" <<
field_iter->getName().str() <<
");" << std::endl;
1603 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1608 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1611 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1614 << s <<
");" << std::endl;
1617 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1620 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1623 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1627 dictStream <<
" R__b.WriteArray((Int_t*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1629 dictStream <<
" R__b.WriteArrayFloat16(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1631 dictStream <<
" R__b.WriteArrayDouble32(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1633 dictStream <<
" R__b.WriteArray(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1640 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" <<
field_iter->getName().str() <<
");" << std::endl;
1647 <<
"=Float16_t(R_Dummy);}" << std::endl;
1653 <<
"=Double32_t(R_Dummy);}" << std::endl;
1675 if (
type.getTypePtr()->isConstantArrayType() &&
1676 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1677 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1684 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1695 }
else if (
type.getTypePtr()->isPointerType()) {
1703 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1730 }
else if (
const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1737 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1741 const char *
constwd =
"const ";
1746 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1750 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1757 <<
field_iter->getName().str() <<
"));" << std::endl;
1768 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1769 <<
" }" << std::endl
1770 <<
"}" << std::endl << std::endl;
1781 const cling::Interpreter &
interp,
1787 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1788 if (
clxx ==
nullptr)
return;
1793 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1811 dictStream <<
"//_______________________________________"
1812 <<
"_______________________________________" << std::endl;
1816 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1817 <<
" if (R__b.IsReading()) {" << std::endl
1818 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1819 <<
" } else {" << std::endl
1820 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1821 <<
" }" << std::endl
1822 <<
"}" << std::endl << std::endl;
1833 const cling::Interpreter &
interp,
1855 for (std::string& arg : InputFiles) {
1858 for (
int j = 0;
j < 3;
j++) {
1859 if (arg[
l] ==
'-') {
1864 if (arg[
l] ==
'!') {
1869 if (arg[
l] ==
'+') {
1885 llvm::SmallString<256>
filestem = llvm::sys::path::filename(arg);
1886 llvm::sys::path::replace_extension(
filestem,
"");
1925 for (
size_t i = 0; i <
nPaths; i += 1 ) {
1974 cling::Interpreter &
interp,
1977 std::ostringstream out;
1981 modGen.WriteUmbrellaHeader(out);
1982 if (
interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1990 modGen.WriteContentHeader(out);
2003 clang::Module *
module =
nullptr)
2006 llvm::SmallVector<char, 128> buffer;
2007 llvm::BitstreamWriter stream(buffer);
2009 std::unique_ptr<llvm::raw_ostream> out =
2024 out->write(&buffer.front(), buffer.size());
2038 assert(
modGen.IsPCH() &&
"modGen must be in PCH mode");
2040 std::string
iSysRoot(
"/DUMMY_SYSROOT/include/");
2056 for (
const std::string &header :
headers) {
2057 includes <<
"#include \"" << header <<
"\"\n";
2061 return result == cling::Interpreter::CompilationResult::kSuccess;
2070#ifdef __INTEL_COMPILER
2083#ifdef __GNUC_MINOR__
2099#ifdef _STLPORT_VERSION
2146 return llvm::sys::path::filename(path).str();
2156 if (std::string::npos != pos) {
2157 dirname.assign(path.begin(), path.begin() + pos + 1);
2225 const cling::Interpreter &
interp)
2227 if (!
decls.empty()) {
2234 names.push_back(
d->getQualifiedNameAsString());
2255 const std::list<std::string> &
nsNames,
2256 const std::list<std::string> &
tdNames,
2257 const std::list<std::string> &
enNames,
2258 const std::list<std::string> &
varNames,
2292 rootmapFile <<
"class " << className << std::endl;
2299 if (className.find(
"<") != std::string::npos)
continue;
2303 auto &header =
headers.front();
2324 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2333 rootmapFile <<
"# List of selected enums and outer classes\n";
2360 if (
foundNsPos == std::string::npos)
return {
"",
""};
2416 std::list<std::string> &
el_list,
2417 std::unordered_set<std::string> &
el_set)
2475 std::cerr <<
"FATAL: A class with normalized name " <<
normalizedName
2476 <<
" was already selected. This means that two different instances of"
2477 <<
" clang::RecordDecl had the same name, which is not possible."
2478 <<
" This can be a hint of a serious problem in the class selection."
2479 <<
" In addition, the generated dictionary would not even compile.\n";
2493 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl)) {
2535 !llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl) &&
2589 if (clang::CXXRecordDecl *
CXXRD =
2590 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2602 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2605 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2608 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2624 if (
interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2625 "#include \"TFile.h\"\n"
2626 "#include \"TObjArray.h\"\n"
2627 "#include \"TVirtualArray.h\"\n"
2628 "#include \"TStreamerElement.h\"\n"
2629 "#include \"TProtoClass.h\"\n"
2630 "#include \"TBaseClass.h\"\n"
2631 "#include \"TListOfDataMembers.h\"\n"
2632 "#include \"TListOfEnums.h\"\n"
2633 "#include \"TListOfEnumsWithLock.h\"\n"
2634 "#include \"TDataMember.h\"\n"
2635 "#include \"TEnum.h\"\n"
2636 "#include \"TEnumConstant.h\"\n"
2637 "#include \"TDictAttributeMap.h\"\n"
2638 "#include \"TMessageHandler.h\"\n"
2639 "#include \"TArray.h\"\n"
2640 "#include \"TRefArray.h\"\n"
2641 "#include \"root_std_complex.h\"\n")
2642 != cling::Interpreter::kSuccess)
2680 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2681 if (
nsName.find(
"(anonymous)") == std::string::npos)
2686 if (!
selClass.GetRecordDecl()->isCompleteDefinition()) {
2690 if (
selClass.RequestOnlyTClass()) {
2698 if (clang::CXXRecordDecl *
CXXRD =
2699 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2703 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2711 }
else if (
CRD->getName() ==
"RVec") {
2712 static const clang::DeclContext *
vecOpsDC =
nullptr;
2714 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2715 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2739 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2743 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2755 if (!
selClass.GetRecordDecl()->isCompleteDefinition() || !
selClass.RequestOnlyTClass()) {
2759 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2814 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2815 <<
"#define R__DICTIONARY_FILENAME " <<
main_dictname << std::endl
2818 <<
"#define R__NO_DEPRECATION" << std::endl
2823 <<
"\n/*******************************************************************/\n"
2824 <<
"#include <stddef.h>\n"
2825 <<
"#include <stdio.h>\n"
2826 <<
"#include <stdlib.h>\n"
2827 <<
"#include <string.h>\n"
2828 <<
"#include <assert.h>\n"
2829 <<
"#define G__DICTIONARY\n"
2830 <<
"#include \"ROOT/RConfig.hxx\"\n"
2831 <<
"#include \"TClass.h\"\n"
2832 <<
"#include \"TDictAttributeMap.h\"\n"
2833 <<
"#include \"TInterpreter.h\"\n"
2834 <<
"#include \"TROOT.h\"\n"
2835 <<
"#include \"TBuffer.h\"\n"
2836 <<
"#include \"TMemberInspector.h\"\n"
2837 <<
"#include \"TInterpreter.h\"\n"
2838 <<
"#include \"TVirtualMutex.h\"\n"
2839 <<
"#include \"TError.h\"\n\n"
2840 <<
"#ifndef G__ROOT\n"
2841 <<
"#define G__ROOT\n"
2843 <<
"#include \"RtypesImp.h\"\n"
2844 <<
"#include \"TIsAProxy.h\"\n"
2845 <<
"#include \"TFileMergeInfo.h\"\n"
2846 <<
"#include <algorithm>\n"
2847 <<
"#include \"TCollectionProxyInfo.h\"\n"
2848 <<
"/*******************************************************************/\n\n"
2849 <<
"#include \"TDataMember.h\"\n\n";
2856 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2857 <<
"namespace std {} using namespace std;\n\n";
2866 dictStream <<
"// Header files passed as explicit arguments\n"
2868 <<
"// Header files passed via #pragma extra_include\n"
2875#if defined(R__IOSSIM) || defined(R__IOS)
2936 for (
unsigned int i = 0; i < m_size; ++i) {
2937 const char *
tmpName = m_tempNames[i].c_str();
2944 if (
ifile.is_open())
2946 if (0 != std::remove(
tmpName)) {
2959 for (
unsigned int i = 0; i < m_size; ++i) {
2960 const char *
tmpName = m_tempNames[i].c_str();
2961 const char *
name = m_names[i].c_str();
2968 if (
ifile.is_open())
2976 llvm::sys::fs::remove(
tmpName);
2992 size_t i = std::distance(m_tempNames.begin(),
2993 find(m_tempNames.begin(), m_tempNames.end(),
tmpFileName));
2994 if (i == m_tempNames.size())
return m_emptyString;
3001 std::cout <<
"Restoring files in temporary file catalog:\n";
3002 for (
unsigned int i = 0; i < m_size; ++i) {
3003 std::cout << m_tempNames[i] <<
" --> " << m_names[i] << std::endl;
3035 static const std::string pattern(
"-Wno-");
3037 if (arg.find(pattern) != 0)
3048 cling::Interpreter &
interp)
3073 if (
qt.isNull())
return qt;
3075 while (
thisQt->isPointerType() ||
3076 thisQt->isReferenceType()) {
3087 const cling::Interpreter &
interp,
3090 std::list<std::string>
headers;
3093 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
3100 if (
const clang::ClassTemplateSpecializationDecl *
tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&
rcd)) {
3103 for (
auto &
tArg :
tsd->getTemplateArgs().asArray()) {
3104 if (clang::TemplateArgument::ArgKind::Type !=
tArg.getKind())
continue;
3125 if (
const clang::FieldDecl *
fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*
declIt)) {
3138 for (
auto & fPar :
methodIt->parameters()) {
3173 if (!
dclCtxt->isStdNamespace()){
3193 if (
argKind != clang::TemplateArgument::Type){
3194 if (
argKind == clang::TemplateArgument::Integral)
continue;
3201 if (
isPOD)
continue;
3226 const cling::Interpreter &
interp)
3229 std::unordered_set<std::string> buffer;
3234 if (
const clang::CXXRecordDecl *
cxxRcd =
3235 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
annotatedRcd.GetRecordDecl())) {
3241 headers.remove_if([&buffer](
const std::string & s) {
3242 return !buffer.insert(s).second;
3255 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(
cxxRcd)){
3264 if (clang::CXXRecordDecl *
cxxRcd =
tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3271 headers.remove_if([&buffer](
const std::string & s) {
3272 return !buffer.insert(s).second;
3303 const cling::Interpreter &
interp)
3311 std::unordered_set<std::string>
fwdDecls;
3354 std::cout <<
"Logs from forward decl printer: \n"
3385 std::cout <<
"Class-headers Mapping:\n";
3401 std::cout << std::endl;
3428 static const std::vector<std::string>
namePrfxes {
3433 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3451 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3465 std::cerr <<
"Error: Class " <<
clName <<
" has been selected but "
3466 <<
"currently the support for its I/O is not yet available. Note that "
3467 <<
clName <<
", even if not selected, will be available for "
3468 <<
"interpreted code.\n";
3472 std::cerr <<
"Error: It is not necessary to explicitly select class "
3473 <<
clName <<
". I/O is supported for it transparently.\n";
3485 bool isLocked =
false;
3488 InterpreterCallbacks(
interp),
3494 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3495 clang::OptionalFileEntryRef , llvm::StringRef ,
3496 llvm::StringRef ,
const clang::Module * ,
3497 clang::SrcMgr::CharacteristicKind )
override
3499 if (isLocked)
return;
3512 fFilesIncludedByLinkdef.clear();
3532 using namespace clang;
3533 if (llvm::StringRef(M->Name).ends_with(
"ACLiC_dict")) {
3539 assert(M &&
"Must have module Core");
3546 llvm::cl::desc(
"Allow implicit build of system modules."),
3548static llvm::cl::list<std::string>
3551 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3554static llvm::cl::opt<std::string>
3556 llvm::cl::desc(
"<output dictionary file>"),
3588 using namespace clang::diag;
3595 const clang::Module *
module = nullptr;
3598 const auto &ID =
Info.getID();
3601 module = fMap.findModule(moduleName);
3607 "Couldn't find module %s in the available modulemaps. This"
3608 "prevents us from correctly diagnosing wrongly built modules.\n",
3639 "Building module '%s' implicitly. If '%s' requires a \n"
3640 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3641 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3651 DiagnosticConsumer::clear();
3657 DiagnosticConsumer::BeginSourceFile(
LangOpts,
PP);
3662 fChild->EndSourceFile();
3663 DiagnosticConsumer::EndSourceFile();
3669 DiagnosticConsumer::finish();
3676#if defined(_WIN32) && defined(_MSC_VER)
3693static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3695static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3706static llvm::cl::opt<VerboseLevel>
3708 llvm::cl::values(
clEnumVal(
v,
"Show errors."),
3717static llvm::cl::opt<bool>
3718gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3721static llvm::cl::opt<bool>
3722gOptReflex(
"reflex", llvm::cl::desc(
"Behave internally like genreflex."),
3724static llvm::cl::opt<bool>
3725gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3728static llvm::cl::opt<std::string>
3730 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3733static llvm::cl::opt<bool>
3735 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3738static llvm::cl::opt<bool>
3739gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3741static llvm::cl::opt<bool>
3742gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3744static llvm::cl::list<std::string>
3746 llvm::cl::desc(
"Generate rootmap file."),
3748static llvm::cl::opt<std::string>
3750 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3752static llvm::cl::opt<bool>
3754 llvm::cl::desc(
"Generate a C++ module."),
3756static llvm::cl::list<std::string>
3758 llvm::cl::desc(
"Specify a C++ modulemap file."),
3761static llvm::cl::opt<bool>
3763 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3765static llvm::cl::opt<bool>
3767 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3769static llvm::cl::opt<bool>
3771 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3773static llvm::cl::opt<bool>
3775 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3777static llvm::cl::opt<bool>
3779 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3780information and another the interactivity support."),
3782static llvm::cl::opt<bool>
3785 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3787static llvm::cl::opt<std::string>
3789 llvm::cl::desc(
"The path to the library of the built dictionary."),
3791static llvm::cl::list<std::string>
3793 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3795static llvm::cl::list<std::string>
3797 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3801static llvm::cl::opt<bool>
3803 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3811static llvm::cl::opt<bool>
3814 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3816static llvm::cl::opt<bool>
3818 llvm::cl::desc(
"Check the selection syntax only."),
3820static llvm::cl::opt<bool>
3822 llvm::cl::desc(
"Fail if there are warnings."),
3824static llvm::cl::opt<bool>
3826 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3828static llvm::cl::opt<std::string>
3830 llvm::cl::desc(
"Specify an isysroot."),
3832 llvm::cl::init(
"-"));
3833static llvm::cl::list<std::string>
3835 llvm::cl::desc(
"Specify an include path."),
3837static llvm::cl::list<std::string>
3839 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3841static llvm::cl::list<std::string>
3843 llvm::cl::desc(
"Specify a system include path."),
3845static llvm::cl::list<std::string>
3847 llvm::cl::desc(
"Specify defined macros."),
3849static llvm::cl::list<std::string>
3851 llvm::cl::desc(
"Specify undefined macros."),
3853static llvm::cl::list<std::string>
3855 llvm::cl::desc(
"Specify compiler diagnostics options."),
3858static llvm::cl::list<std::string>
3860 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file | selection xml file>"),
3862static llvm::cl::list<std::string>
3864 llvm::cl::desc(
"Consumes all unrecognized options."),
3867static llvm::cl::SubCommand
3870static llvm::cl::list<std::string>
3872 llvm::cl::desc(
"Consumes options and sends them to cling."),
3901 for (
const std::string &header :
modGen.GetHeaders()) {
3906 clang::ConstSearchDirIterator *
CurDir =
nullptr;
3908 header, clang::SourceLocation(),
3911 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>>(),
3950 clang::HeaderSearch &
headerSearch =
CI->getPreprocessor().getHeaderSearchInfo();
3954 clang::Module *
module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3970 msgStream <<
"after creating module \"" <<
module->Name << "\" ";
3971 if (!
module->PresumedModuleMapFile.empty())
3972 msgStream <<
"using modulemap \"" <<
module->PresumedModuleMapFile << "\" ";
3973 msgStream <<
"the following headers are not part of that module:\n";
3977 msgStream <<
" (already part of module \"" <<
H[1] <<
"\")";
3993 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
4003 [](
const std::array<std::string, 2>&
HdrMod) { return HdrMod[0];});
4041 llvm::PrettyStackTraceProgram
X(
argc,
argv);
4044#if defined(R__WIN32) && !defined(R__WINGCC)
4065 auto &
opts = llvm::cl::getRegisteredOptions();
4068 llvm::cl::desc(
"Alias for -help"),
4069 llvm::cl::aliasopt(*
optHelp));
4071 llvm::cl::desc(
"Alias for -help"),
4072 llvm::cl::aliasopt(*
optHelp));
4074 llvm::cl::ParseCommandLineOptions(
argc,
argv,
"rootcling");
4095 return interp->getDiagnostics().hasFatalErrorOccurred();
4112 llvm::cl::PrintHelpMessage();
4127 if ((fp =
fopen(
filein.c_str(),
"r")) ==
nullptr) {
4155 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4156 llvm::cl::PrintHelpMessage();
4168 std::list<std::string>
diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4174 if (GetErrorIgnoreLevel() >
kWarning)
4176 GetWarningsAreErrors() =
true;
4190 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4224 std::vector<std::string>
pcmArgs;
4238 [&](
const std::string& path){
4239 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4246 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(
gDriverConfig->fTROOT__GetEtcDir()));
4252 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4253#elif defined(R__WIN32)
4254 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4261 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4269 clingArgs.push_back(
"-fmodules-embed-all-files");
4333 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4334 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4335 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4336 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4338 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4339 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4343 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4345 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4347 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4348 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4349 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4350 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4351 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4352 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4353 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4355 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4370 std::cerr <<
"Argument \""<<
clingArg <<
"\" is not a supported cling argument. "
4371 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4379 cling::Interpreter*
interpPtr =
nullptr;
4407 clang::CompilerInstance *
CI =
interp.getCI();
4409 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4410 CI->getSourceManager().setAllFilesAreTransient(
true);
4412 clang::Preprocessor &
PP =
CI->getPreprocessor();
4422 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4433 interp.DumpIncludePath();
4438 interp.printIncludedFiles(llvm::outs());
4439 llvm::outs() <<
"\n\n";
4440 llvm::outs().flush();
4444 =
interp.getCI()->getASTContext().getLangOpts();
4445#define LANGOPT(Name, Bits, Default, Description) \
4446 ROOT::TMetaUtils::Info(nullptr, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4447#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4448#include "clang/Basic/LangOptions.def"
4452 interp.getOptions().ErrorOut =
true;
4453 interp.enableRawInput(
true);
4457 if (
DepMod.ends_with(
"_rdict.pcm")) {
4464 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4474 if (
interp.declare(
"#include <assert.h>\n"
4475 "#include \"Rtypes.h\"\n"
4476 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4484 if (
interp.declare(
"#include <string>\n"
4485 "#include <RtypesCore.h>\n"
4486 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4582 std::stringstream res;
4583 const char*
delim=
"\n";
4586 std::ostream_iterator<std::string>(res,
delim));
4587 if (
interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4596 clang::PragmaNamespace(
pragma) {}
4597 void HandlePragma(clang::Preprocessor &
PP,
4599 clang::Token &
tok)
override {
4600 PP.DiscardUntilEndOfDirective();
4687 if (
dh != std::string::npos) {
4751 if (file.is_open()) {
4764 clingArgs.push_back(
"-Ietc/cling/cint");
4784 if (file.is_open()) {
4825 <<
"#include \"TVirtualObject.h\"\n"
4826 <<
"#include <vector>\n"
4827 <<
"#include \"TSchemaHelper.h\"\n\n";
4867 scan.
Scan(
CI->getASTContext());
4890 if (
annRcd.RequestNoInputOperator()) {
5057 [](
const std::string &
a,
const std::string &
b) -> std::string {
5058 if (a.empty()) return b;
5059 else return a +
" " + b;
5089 std::list<std::string>
nsNames;
5132 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
5133 CI->getSema().getASTConsumer().HandleTranslationUnit(
CI->getSema().getASTContext());
5169 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5183 for (
int i = 1; i <
argc; ++i) {
5186 args.push_back(
argv[i]);
5196 std::cout <<
"Args: \n";
5197 for (std::vector<std::string>::iterator it = args.begin();
5198 it < args.end(); ++it) {
5199 std::cout << i <<
") " << *it << std::endl;
5213 if (std::string::npos !=
result) {
5225 const unsigned int size(str.size());
5226 char *
a =
new char[
size + 1];
5260 const std::string &
optName =
"")
5272 const std::string &
optName =
"")
5289 const std::vector<std::string> &
pcmsNames,
5290 const std::vector<std::string> &
includes,
5293 const std::vector<std::string> &
warnings,
5331 "*** genreflex: No rootmap lib and several header specified!\n");
5424 for (
int i = 0; i <
argc; i++) {
5430 std::cout <<
cmd << std::endl;
5439 for (
int i = 0; i <
argc; i++)
5454 const std::vector<std::string> &
pcmsNames,
5455 const std::vector<std::string> &
includes,
5458 const std::vector<std::string> &
warnings,
5483 for (
unsigned int i = 0; i <
headersNames.size(); ++i) {
5525 std::vector<std::string> &values)
5530 values.reserve(
nVals);
5535 << opt->arg << std::endl;
5537 values.push_back(opt->arg);
5552 "*** genereflex: %s is not supported anymore.\n",
5645 "********************************************************************************\n"
5646 "* The genreflex utility does not allow to generate C++ modules containing *\n"
5647 "* reflection information required at runtime. Please use rootcling instead *\n"
5648 "* To print the rootcling invocation that corresponds to the current genreflex *\n"
5649 "* invocation please use the --print-rootcling-invocation flag. *\n"
5650 "********************************************************************************\n"
5652 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5653 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5657 "--print-rootcling-invocation\n"
5658 " Print to screen the rootcling invocation corresponding to the current \n"
5659 " genreflex invocation.\n";
5662 "-s, --selection_file\tSelection filename\n"
5663 " Class selection file to specify for which classes the dictionary\n"
5664 " will be generated. The final set can be crafted with exclusion and\n"
5665 " exclusion rules.\n"
5666 " Properties can be specified. Some have special meaning:\n"
5667 " - name [string] name of the entity to select with an exact matching\n"
5668 " - pattern [string] name with wildcards (*) to select entities\n"
5669 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5670 " file where the C++ entities reside and not to C++ entities themselves.\n"
5671 " - transient/persistent [string: true/false] The fields to which they are\n"
5672 " applied will not be persistified if requested.\n"
5673 " - comment [string]: what you could write in code after an inline comment\n"
5674 " without \"//\". For example comment=\"!\" or \"||\".\n"
5675 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5676 " Default value is 'false'\n"
5677 " - rntupleStreamerMode [true/false]: enforce streamed or native writing for RNTuple.\n"
5678 " If unset, RNTuple stores classes in split mode or fails if the class cannot be split.\n"
5679 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5680 " to 'true'. Default value is 'false'\n"
5684 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5685 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5686 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5687 " [noInputOperator=\"true/false\"]\n"
5688 " [rntupleStreamerMode=\"true/false\"] />\n"
5689 " <class name=\"classname\" >\n"
5690 " <field name=\"m_transient\" transient=\"true\"/>\n"
5691 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5692 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5693 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5695 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5696 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5697 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5700 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5701 " <method name=\"unwanted\" />\n"
5706 " If no selection file is specified, the class with the filename without\n"
5707 " extension will be selected, i.e. myClass.h as argument without any\n"
5708 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5711 "-o, --output\tOutput filename\n"
5712 " Output file name. If an existing directory is specified instead of a file,\n"
5713 " then a filename will be built using the name of the input file and will\n"
5714 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5715 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5716 " have unique names.\n";
5720 "-l, --library\tTarget library\n"
5721 " The flag -l must be followed by the name of the library that will\n"
5722 " contain the object file corresponding to the dictionary produced by\n"
5723 " this invocation of genreflex.\n"
5724 " The name takes priority over the one specified for the rootmapfile.\n"
5725 " The name influences the name of the created pcm:\n"
5726 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5727 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5728 " Any \"liblib\" occurence is transformed in the expected \"lib\".\n"
5729 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5730 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5733 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5734 " This file lists the autoload keys. For example classes for which the\n"
5735 " reflection information is provided.\n"
5736 " The format of the rootmap is the following:\n"
5737 " - Forward declarations section\n"
5738 " - Libraries sections\n"
5739 " Rootmaps can be concatenated together, for example with the cat util.\n"
5740 " In order for ROOT to pick up the information in the rootmaps, they\n"
5741 " have to be located in the library path and have the .rootmap extension.\n"
5742 " An example rootmap file could be:\n"
5744 " template <class T> class A;\n"
5745 " [ libMyLib.so ]\n"
5746 " class A<double>\n"
5752 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5768 "",
"print-rootcling-invocation",
5794 "--multiDict\tSupport for many dictionaries in one library\n"
5795 " Form correct pcm names if multiple dictionaries will be in the same\n"
5796 " library (needs target library switch. See its documentation).\n"
5803 "" ,
"noGlobalUsingStd" ,
5805 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5806 " All header files must have sumbols from std:: namespace fully qualified\n"
5812 "s" ,
"selection_file" ,
5828 "" ,
"rootmap-lib" ,
5836 "" ,
"interpreteronly",
5838 "--interpreteronly\tDo not generate I/O related information.\n"
5839 " Generate minimal dictionary required for interactivity.\n"
5847 "--split\tSplit the dictionary\n"
5848 " Split in two the dictionary, isolating the part with\n"
5849 " ClassDef related functions in a separate file.\n"
5857 "-m \tPcm file loaded before any header (option can be repeated).\n"
5865 "-v, --verbose\tPrint some debug information.\n"
5873 "--debug\tPrint all debug information.\n"
5881 "--quiet\tPrint only warnings and errors (default).\n"
5889 "--silent\tPrint no information at all.\n"
5895 "" ,
"writeEmptyPCM",
5897 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5905 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5914 "--help\tPrint usage and exit.\n"
5920 "",
"fail_on_warnings",
5922 "--fail_on_warnings\tFail on warnings and errors.\n"
5928 "",
"selSyntaxOnly",
5930 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5936 "" ,
"noIncludePaths",
5938 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5977 "" ,
"no_membertypedefs" ,
5985 "" ,
"no_templatetypedefs" ,
5990 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
6004 std::vector<ROOT::option::Option> options(
stats.options_max);
6005 std::vector<ROOT::option::Option> buffer(
stats.buffer_max);
6011 if (parse.
error()) {
6047 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
6072 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6092 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6244 if (std::string::npos !=
exeName.find(
"genreflex"))
6252 ROOT::TMetaUtils::Info(
nullptr,
"Problems have been detected during the generation of the dictionary.\n");
Select classes and assign properties using C++ syntax.
The file contains utilities which are foundational and could be used across the core component of ROO...
This is the only file required to use The Lean Mean C++ Option Parser.
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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.
CheckModuleBuildClient(clang::DiagnosticConsumer *Child, bool OwnsChild, clang::ModuleMap &Map)
clang::DiagnosticConsumer * fChild
~CheckModuleBuildClient()
virtual void BeginSourceFile(const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) override
virtual void finish() override
virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override
virtual void clear() override
virtual bool IncludeInDiagnosticCounts() const override
virtual void EndSourceFile() override
const_iterator begin() const
const_iterator end() const
A parsed option from the command line together with its argument if it has one.
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
bool error()
Returns true if an unrecoverable error occurred while parsing options.
void Scan(const clang::ASTContext &C)
std::vector< ROOT::TMetaUtils::AnnotatedRecordDecl > ClassColl_t
const DeclsSelRulesMap_t & GetDeclsSelRulesMap() const
FunctionColl_t fSelectedFunctions
std::vector< const clang::FunctionDecl * > FunctionColl_t
NamespaceColl_t fSelectedNamespaces
TypedefColl_t fSelectedTypedefs
DeclCallback SetRecordDeclCallback(DeclCallback callback)
Set the callback to the RecordDecl and return the previous one.
std::map< const clang::Decl *, const BaseSelectionRule * > DeclsSelRulesMap_t
EnumColl_t fSelectedEnums
std::vector< const clang::TypedefNameDecl * > TypedefColl_t
std::vector< const clang::VarDecl * > VariableColl_t
static bool GetDeclQualName(const clang::Decl *D, std::string &qual_name)
VariableColl_t fSelectedVariables
std::vector< const clang::EnumDecl * > EnumColl_t
ClassColl_t fSelectedClasses
The class representing the collection of selection rules.
void InclusionDirective(clang::SourceLocation, const clang::Token &, llvm::StringRef FileName, bool IsAngled, clang::CharSourceRange, clang::OptionalFileEntryRef, llvm::StringRef, llvm::StringRef, const clang::Module *, clang::SrcMgr::CharacteristicKind) override
std::list< std::string > & fFilesIncludedByLinkdef
void EnteredSubmodule(clang::Module *M, clang::SourceLocation ImportLoc, bool ForPragma) override
TRootClingCallbacks(cling::Interpreter *interp, std::list< std::string > &filesIncludedByLinkdef)
Little helper class to bookkeep the files names which we want to make temporary.
void addFileName(std::string &nameStr)
Adds the name and the associated temp name to the catalog.
const std::string & getFileName(const std::string &tmpFileName)
std::vector< std::string > m_names
std::vector< std::string > m_tempNames
const std::string m_emptyString
std::string getTmpFileName(const std::string &filename)
static bool FromCygToNativePath(std::string &path)
std::string GetCurrentDir()
std::string MakePathRelative(const std::string &path, const std::string &base, bool isBuildingROOT=false)
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
@ 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)
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))
void SetRootSys()
Set the ROOTSYS env var based on the executable location.
bool CheckInputOperator(const char *what, const char *proto, const string &fullname, const clang::RecordDecl *cl, cling::Interpreter &interp)
Check if the specified operator (what) has been properly declared if the user has requested a custom ...
void GenerateNecessaryIncludes(std::ostream &dictStream, const std::string &includeForSource, const std::string &extraIncludes)
void StrcpyArg(string &dest, const char *original)
Copy the command line argument, stripping MODULE/inc if necessary.
static llvm::cl::list< std::string > gOptRootmapLibNames("rml", llvm::cl::ZeroOrMore, llvm::cl::desc("Generate rootmap file."), llvm::cl::cat(gRootclingOptions))
void ParseRootMapFile(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map.
static llvm::cl::opt< bool > gOptCxxModule("cxxmodule", llvm::cl::desc("Generate a C++ module."), llvm::cl::cat(gRootclingOptions))
std::pair< std::string, std::string > GetExternalNamespaceAndContainedEntities(const std::string line)
Performance is not critical here.
void AddPlatformDefines(std::vector< std::string > &clingArgs)
static std::string GenerateFwdDeclString(const RScanner &scan, const cling::Interpreter &interp)
Generate the fwd declarations of the selected entities.
static llvm::cl::opt< bool > gOptFailOnWarnings("failOnWarnings", llvm::cl::desc("Fail if there are warnings."), llvm::cl::cat(gRootclingOptions))
const char * CopyArg(const char *original)
If the argument starts with MODULE/inc, strip it to make it the name we can use in #includes.
string GetNonConstMemberName(const clang::FieldDecl &m, const string &prefix="")
Return the name of the data member so that it can be used by non-const operation (so it includes a co...
static llvm::cl::list< std::string > gOptIncludePaths("I", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify an include path."), llvm::cl::cat(gRootclingOptions))
void WriteAutoStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
void ExtractSelectedNamespaces(RScanner &scan, std::list< std::string > &nsList)
Loop on selected classes and put them in a list.
static bool IncludeHeaders(const std::vector< std::string > &headers, cling::Interpreter &interpreter)
Includes all given headers in the interpreter.
clang::QualType GetPointeeTypeIfPossible(const clang::QualType &qt)
Get the pointee type if possible.
void AnnotateDecl(clang::CXXRecordDecl &CXXRD, const RScanner::DeclsSelRulesMap_t &declSelRulesMap, cling::Interpreter &interpreter, bool isGenreflex)
static llvm::cl::opt< VerboseLevel > gOptVerboseLevel(llvm::cl::desc("Choose verbosity level:"), llvm::cl::values(clEnumVal(v, "Show errors."), clEnumVal(v0, "Show only fatal errors."), clEnumVal(v1, "Show errors (the same as -v)."), clEnumVal(v2, "Show warnings (default)."), clEnumVal(v3, "Show notes."), clEnumVal(v4, "Show information.")), llvm::cl::init(v2), llvm::cl::cat(gRootclingOptions))
void GenerateLinkdef(llvm::cl::list< std::string > &InputFiles, std::string &code_for_parser)
static llvm::cl::opt< std::string > gOptRootMapFileName("rmf", llvm::cl::desc("Generate a rootmap file with the specified name."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptInlineInput("inlineInputHeader", llvm::cl::desc("Does not generate #include <header> but expands the header content."), llvm::cl::cat(gRootclingOptions))
bool isPointerToPointer(const clang::FieldDecl &m)
int CreateNewRootMapFile(const std::string &rootmapFileName, const std::string &rootmapLibName, const std::list< std::string > &classesDefsList, const std::list< std::string > &classesNames, const std::list< std::string > &nsNames, const std::list< std::string > &tdNames, const std::list< std::string > &enNames, const std::list< std::string > &varNames, const HeadersDeclsMap_t &headersClassesMap, const std::unordered_set< std::string > headersToIgnore)
Generate a rootmap file in the new format, like { decls } namespace A { namespace B { template <typen...
static llvm::cl::opt< std::string > gOptDictionaryFileName(llvm::cl::Positional, llvm::cl::desc("<output dictionary file>"), llvm::cl::cat(gRootclingOptions))
bool IsSelectionXml(const char *filename)
bool IsGoodLibraryName(const std::string &name)
llvm::StringRef GrabIndex(const cling::Interpreter &interp, const clang::FieldDecl &member, int printError)
GrabIndex returns a static string (so use it or copy it immediately, do not call GrabIndex twice in t...
static llvm::cl::opt< bool > gOptMultiDict("multiDict", llvm::cl::desc("If this library has multiple separate LinkDef files."), llvm::cl::cat(gRootclingOptions))
bool IsSelectionFile(const char *filename)
const std::string GenerateStringFromHeadersForClasses(const HeadersDeclsMap_t &headersClassesMap, const std::string &detectedUmbrella, bool payLoadOnly=false)
Generate a string for the dictionary from the headers-classes map.
bool IsSupportedClassName(const char *name)
static llvm::cl::opt< bool > gOptIgnoreExistingDict("r", llvm::cl::desc("Deprecated. Similar to -f but it ignores the dictionary generation. \
When -r is present rootcling becomes a tool to generate rootmaps (and capability files)."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
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.
int ROOT_rootcling_Driver(int argc, char **argv, const ROOT::Internal::RootCling::DriverConfig &config)
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Describes an option, its help text (usage) and how it should be parsed.
static option::ArgStatus Required(const option::Option &option, bool msg)
Determines the minimum lengths of the buffer and options arrays used for Parser.