12#include "rootclingCommandLineOptionsHelp.h"
14#include "RConfigure.h"
34#include <unordered_map>
35#include <unordered_set>
47#define PATH_MAX _MAX_PATH
55#include <mach-o/dyld.h>
63#include <libprocstat.h>
72#include "cling/Interpreter/Interpreter.h"
73#include "cling/Interpreter/InterpreterCallbacks.h"
74#include "cling/Interpreter/LookupHelper.h"
75#include "cling/Interpreter/Value.h"
76#include "clang/AST/CXXInheritance.h"
77#include "clang/Basic/Diagnostic.h"
78#include "clang/Frontend/CompilerInstance.h"
79#include "clang/Frontend/FrontendActions.h"
80#include "clang/Frontend/FrontendDiagnostic.h"
81#include "clang/Lex/HeaderSearch.h"
82#include "clang/Lex/Preprocessor.h"
83#include "clang/Lex/ModuleMap.h"
84#include "clang/Lex/Pragma.h"
85#include "clang/Sema/Sema.h"
86#include "clang/Serialization/ASTWriter.h"
87#include "cling/Utils/AST.h"
89#include "llvm/ADT/StringRef.h"
91#include "llvm/Support/CommandLine.h"
92#include "llvm/Support/Path.h"
93#include "llvm/Support/PrettyStackTrace.h"
94#include "llvm/Support/Signals.h"
118#include <mach-o/dyld.h>
123#define strcasecmp _stricmp
124#define strncasecmp _strnicmp
132#define rootclingStringify(s) rootclingStringifyx(s)
133#define rootclingStringifyx(s) #s
140using std::string, std::map, std::ifstream, std::ofstream, std::endl, std::ios, std::vector;
171 gDriverConfig->fAddTypedefToROOTFile(
td->getQualifiedNameAsString().c_str());
179 if (clang::isa<clang::TranslationUnitDecl>(
en->getDeclContext())
180 || clang::isa<clang::LinkageSpecDecl>(
en->getDeclContext())
181 || clang::isa<clang::NamespaceDecl>(
en->getDeclContext()))
182 gDriverConfig->fAddEnumToROOTFile(
en->getQualifiedNameAsString().c_str());
196#if defined(__linux) || defined(__linux__)
205 if (
ret > 0 &&
ret < 1024) {
239 const cling::Interpreter &
interp)
257 clang::ASTContext &C =
decl.getASTContext();
263 if (! it->GetAttributeValue(propNames::name,
varName))
continue;
267 BaseSelectionRule::AttributesMap_t::iterator iter;
270 const std::string &
name = iter->first;
271 const std::string &
value = iter->second;
273 if (
name == propNames::name)
continue;
278 if (
name == propNames::iotype &&
279 (
decl.getType()->isArrayType() ||
decl.getType()->isPointerType())) {
280 const char *
msg =
"Data member \"%s\" is an array or a pointer. "
281 "It is not possible to assign to it the iotype \"%s\". "
282 "This transformation is possible only with data members "
283 "which are not pointers or arrays.\n";
293 if (
name == propNames::comment) {
294 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
value,
nullptr, 0));
298 if ((
name == propNames::transient &&
value ==
"true") ||
299 (
name == propNames::persistent &&
value ==
"false")) {
304 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
"!",
nullptr, 0));
330 using namespace clang;
332 llvm::StringRef comment;
349 BaseSelectionRule::AttributesMap_t::iterator iter;
352 const std::string &
name =
attr.first;
364 for (CXXRecordDecl::decl_iterator
I =
CXXRD.decls_begin(),
365 E =
CXXRD.decls_end();
I != E; ++
I) {
369 if (!(*I)->isImplicit()
381 if (comment.size()) {
384 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
391 (*I)->addAttr(AnnotateAttr::CreateImplicit(C, comment.str(),
nullptr, 0));
415 while (
const clang::ConstantArrayType *
subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual())) {
419 return len.getLimitedValue();
425 const cling::Interpreter &
interp)
430 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
437 const cling::Interpreter &
interp)
482 fprintf(
stderr,
"rootcling: error getting realpath of rootcling!");
487 char *
ep =
new char[
nche];
495 if (!
strncmp(s + 1,
"rootcling_stage1.exe", 20)) {
499 }
else if (!
strncmp(s + 1,
"rootcling_stage1", 16)) {
544 size_t *end =
nullptr)
547 if (
line[0] !=
'#')
return false;
572 clang::Module *M =
recordDecl->getOwningModule()->getTopLevelModule();
590 if (classname.find(
':') == std::string::npos)
return;
593 int slen = classname.size();
594 for (
int k = 0; k <
slen; ++k) {
595 if (classname[k] ==
':') {
596 if (k + 1 >=
slen || classname[k + 1] !=
':') {
601 string base = classname.substr(0, k);
610 }
else if (classname[k] ==
'<') {
622 std::string classname;
624 while (file >>
line) {
626 if (
line.find(
"Library.") != 0)
continue;
628 int pos =
line.find(
":", 8);
629 classname =
line.substr(8, pos - 8);
635 while (
line[0] ==
' ')
line.replace(0, 1,
"");
639 if (classname ==
"ROOT::TImpProxy") {
658 const std::unordered_map<char, unsigned int>
keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
661 if (
line ==
"{ decls }") {
663 if (
line[0] ==
'[')
break;
670 while (
libs[0] ==
' ')
libs.replace(0, 1,
"");
694 if (llvm::sys::fs::is_directory(
filename))
continue;
702 file.seekg(0, std::ios::beg);
723 const string &fullname,
724 const clang::RecordDecl *cl,
725 cling::Interpreter &
interp)
728 const clang::FunctionDecl *
method
733 clang::TranslationUnitDecl *
TU =
734 cl->getASTContext().getTranslationUnitDecl();
739 if (
method !=
nullptr && (
method->getAccess() == clang::AS_public ||
method->getAccess() == clang::AS_none)) {
758 "in this version of ROOT, the option '!' used in a linkdef file\n"
759 " implies the actual existence of customized operators.\n"
760 " The following declaration is now required:\n"
775 int ncha = fullname.length() + 13;
800 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
811 "because it inherits from TObject but does not "
812 "have its own ClassDef.\n",
825 if (
m.getType().isConstQualified()) {
826 string ret =
"const_cast< ";
836 ret +=
m.getName().str();
840 return prefix +
m.getName().str();
850 const cling::Interpreter &
interp,
868 if (!
clxx ||
clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
870 const clang::ClassTemplateSpecializationDecl *
tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (
clxx);
878 const char *
tcl1 =
nullptr, *
tcl2 =
nullptr;
880 clang::QualType
ti =
arg0.getAsType();
898 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
904 if (
arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
908 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
910 }
else if (
m.getType()->isPointerType()) {
917 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
929 <<
" *" <<
stlName.c_str() <<
" = new " <<
stlType.c_str() <<
";" << std::endl
930 <<
" " <<
stlType.c_str() <<
" &R__stl = **" <<
stlName.c_str() <<
";" << std::endl;
934 <<
" " <<
stlName.c_str() <<
"[R__l] = new " <<
stlType.c_str() <<
";" << std::endl
935 <<
" " <<
stlType.c_str() <<
" &R__stl = *" <<
stlName.c_str() <<
"[R__l];" << std::endl;
939 dictStream <<
" R__stl.clear();" << std::endl;
942 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
943 <<
" if (R__tcl1==0) {" << std::endl
944 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
945 <<
fulName1.c_str() <<
"!\");" << std::endl
946 <<
" return;" << std::endl
947 <<
" }" << std::endl;
950 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
951 <<
" if (R__tcl2==0) {" << std::endl
952 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
953 <<
fulName2.c_str() <<
"!\");" << std::endl
954 <<
" return;" << std::endl
955 <<
" }" << std::endl;
959 <<
" R__b >> R__n;" << std::endl;
962 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
964 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
990 <<
" std::pair<Value_t const, " <<
tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
991 <<
" R__stl.insert(R__t3);" << std::endl;
999 dictStream <<
" R__stl.insert(R__t);" << std::endl;
1004 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
1007 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
1013 <<
" }" << std::endl;
1020 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
1038 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
1039 <<
" R__b << R__n;" << std::endl
1040 <<
" if(R__n) {" << std::endl;
1043 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" <<
fulName1.c_str() <<
"));" << std::endl
1044 <<
" if (R__tcl1==0) {" << std::endl
1045 <<
" Error(\"" <<
stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
1046 <<
fulName1.c_str() <<
"!\");" << std::endl
1047 <<
" return;" << std::endl
1048 <<
" }" << std::endl;
1051 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" <<
fulName2.c_str() <<
"));" << std::endl
1052 <<
" if (R__tcl2==0) {" << std::endl
1053 <<
" Error(\"" <<
stlName.c_str() <<
"streamer\",\"Missing the TClass object for " <<
fulName2.c_str() <<
"!\");" << std::endl
1054 <<
" return;" << std::endl
1055 <<
" }" << std::endl;
1059 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
1070 <<
" }" << std::endl
1071 <<
" }" << std::endl;
1093 if (
m.getType()->isConstantArrayType()) {
1094 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1095 dictStream <<
"// Array of pointer to std::string are not supported (" <<
fieldname <<
"\n";
1098 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1101 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1102 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1103 fullIdx <<
"[R__i" << dim <<
"]";
1104 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1107 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1111 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1112 if (
m.getType()->isPointerType())
1114 <<
fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1120 if (
m.getType()->isPointerType())
1122 <<
fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1123 else if (
m.getType()->isConstantArrayType()) {
1125 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1128 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1129 <<
arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1130 fullIdx <<
"[R__i" << dim <<
"]";
1131 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1136 dictStream <<
" { TString R__str = " <<
fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1147 if (
m.getType()->isPointerType()) {
1148 if (
m.getType()->getPointeeType()->isPointerType()) {
1160 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1162 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1165 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1187 dictStream <<
"#include \"TInterpreter.h\"\n";
1189 dictStream <<
"//_______________________________________"
1190 <<
"_______________________________________" << std::endl;
1192 dictStream <<
"atomic_TClass_ptr " <<
clsname <<
"::fgIsA(nullptr); // static to hold class pointer" << std::endl
1195 <<
"//_______________________________________"
1196 <<
"_______________________________________" << std::endl;
1198 dictStream <<
"const char *" <<
clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1199 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1201 dictStream <<
"//_______________________________________"
1202 <<
"_______________________________________" << std::endl;
1204 dictStream <<
"const char *" <<
clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1205 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1206 <<
"*)nullptr)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1208 <<
"//_______________________________________"
1209 <<
"_______________________________________" << std::endl;
1211 dictStream <<
"int " <<
clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1212 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1213 <<
"*)nullptr)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1215 <<
"//_______________________________________"
1216 <<
"_______________________________________" << std::endl;
1218 dictStream <<
"TClass *" <<
clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1222 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1223 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1224 <<
"*)nullptr)->GetClass();" << std::endl
1225 <<
" return fgIsA;\n"
1226 <<
"}" << std::endl << std::endl
1228 <<
"//_______________________________________"
1229 <<
"_______________________________________" << std::endl;
1231 dictStream <<
"TClass *" <<
clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1235 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1236 dictStream << fullname <<
"*)nullptr)->GetClass(); }" << std::endl;
1239 <<
"}" << std::endl << std::endl;
1251 cling::Interpreter &
interp,
1254 if (cl->isAnonymousNamespace()) {
1266 if (classname !=
"ROOT") {
1270 dictStream <<
" namespace ROOTDict {" << std::endl;
1273 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1280 <<
" // Function generating the singleton type initializer" << std::endl
1283 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1284 <<
" {" << std::endl
1286 <<
" ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1287 <<
" {" << std::endl
1290 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1292 <<
" instance(\"" << classname.c_str() <<
"\", ";
1295 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1301 for (
unsigned int i = 0; i <
filename.length(); i++) {
1305 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1309 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1316 <<
" return &instance;" << std::endl
1317 <<
" }" << std::endl
1318 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1319 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1320 <<
" // Static variable to force the class initialization" << std::endl
1322 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1323 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1326 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1327 <<
" static TClass *" <<
mappedname.c_str() <<
"_Dictionary() {" << std::endl
1328 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1329 <<
" }" << std::endl << std::endl;
1348 llvm::StringRef
where;
1351 if (
index.size() == 0 && printError) {
1358 errorstring =
"has not been defined before the array";
1361 errorstring =
"is a private member of a parent class";
1370 if (
where.size() == 0) {
1372 member.getParent()->getName().str().c_str(),
member.getName().str().c_str());
1384 const cling::Interpreter &
interp,
1388 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1389 if (
clxx ==
nullptr)
return;
1402 dictStream <<
"//_______________________________________"
1403 <<
"_______________________________________" << std::endl;
1405 dictStream <<
"void " <<
clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1406 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1415 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1424 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1426 <<
" baseClass" <<
basestreamer <<
"::Streamer(R__b);" << std::endl;
1434 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1435 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1446 string classname = fullname;
1447 if (
strstr(fullname.c_str(),
"::")) {
1449 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1450 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1451 classname =
"thisClass";
1453 for (
int i = 0; i < 2; i++) {
1458 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1459 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1460 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1462 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1464 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1469 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1478 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1479 <<
" typedef " <<
base_fullname <<
" baseClass" << base <<
";" << std::endl
1480 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1489 for (clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
1495 std::string
type_name =
type.getAsString(
clxx->getASTContext().getPrintingPolicy());
1512 if (
strncmp(comment,
"!", 1)) {
1516 if (
type.getTypePtr()->isConstantArrayType() &&
1517 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1518 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1525 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1527 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());
1530 dictStream <<
" ;//R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1532 }
else if (
type.getTypePtr()->isPointerType()) {
1536 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1539 dictStream <<
" //R__b.WriteArray(" <<
field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1548 <<
"," <<
indexvar.str() <<
");" << std::endl;
1551 <<
"," <<
indexvar.str() <<
");" << std::endl;
1554 <<
"," <<
indexvar.str() <<
");" << std::endl;
1561 dictStream <<
" R__b.WriteFastArrayDouble32("
1569 }
else if (
type.getTypePtr()->isArrayType()) {
1571 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1573 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1577 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1580 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1583 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1588 dictStream <<
" R__b.ReadStaticArray((Int_t*)" <<
field_iter->getName().str() <<
");" << std::endl;
1591 dictStream <<
" R__b.ReadStaticArrayFloat16(" <<
field_iter->getName().str() <<
");" << std::endl;
1593 dictStream <<
" R__b.ReadStaticArrayDouble32(" <<
field_iter->getName().str() <<
");" << std::endl;
1596 <<
"*)" <<
field_iter->getName().str() <<
");" << std::endl;
1601 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1604 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1607 << s <<
");" << std::endl;
1610 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1613 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1616 <<
"*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1620 dictStream <<
" R__b.WriteArray((Int_t*)" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1622 dictStream <<
" R__b.WriteArrayFloat16(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1624 dictStream <<
" R__b.WriteArrayDouble32(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1626 dictStream <<
" R__b.WriteArray(" <<
field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1633 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" <<
field_iter->getName().str() <<
");" << std::endl;
1640 <<
"=Float16_t(R_Dummy);}" << std::endl;
1646 <<
"=Double32_t(R_Dummy);}" << std::endl;
1668 if (
type.getTypePtr()->isConstantArrayType() &&
1669 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1670 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1677 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1688 }
else if (
type.getTypePtr()->isPointerType()) {
1696 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(),
field_iter->getName().str().c_str());
1723 }
else if (
const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1730 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1734 const char *
constwd =
"const ";
1739 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1743 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1750 <<
field_iter->getName().str() <<
"));" << std::endl;
1761 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1762 <<
" }" << std::endl
1763 <<
"}" << std::endl << std::endl;
1774 const cling::Interpreter &
interp,
1780 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1781 if (
clxx ==
nullptr)
return;
1786 for (clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
1804 dictStream <<
"//_______________________________________"
1805 <<
"_______________________________________" << std::endl;
1809 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1810 <<
" if (R__b.IsReading()) {" << std::endl
1811 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1812 <<
" } else {" << std::endl
1813 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1814 <<
" }" << std::endl
1815 <<
"}" << std::endl << std::endl;
1826 const cling::Interpreter &
interp,
1848 for (std::string& arg : InputFiles) {
1851 for (
int j = 0;
j < 3;
j++) {
1852 if (arg[
l] ==
'-') {
1857 if (arg[
l] ==
'!') {
1862 if (arg[
l] ==
'+') {
1878 llvm::SmallString<256>
filestem = llvm::sys::path::filename(arg);
1879 llvm::sys::path::replace_extension(
filestem,
"");
1918 for (
size_t i = 0; i <
nPaths; i += 1 ) {
1967 cling::Interpreter &
interp,
1970 std::ostringstream out;
1974 modGen.WriteUmbrellaHeader(out);
1975 if (
interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1983 modGen.WriteContentHeader(out);
1996 clang::Module *
module =
nullptr)
1999 llvm::SmallVector<char, 128> buffer;
2000 llvm::BitstreamWriter stream(buffer);
2002 std::unique_ptr<llvm::raw_ostream> out =
2017 out->write(&buffer.front(), buffer.size());
2031 assert(
modGen.IsPCH() &&
"modGen must be in PCH mode");
2033 std::string
iSysRoot(
"/DUMMY_SYSROOT/include/");
2049 for (
const std::string &header :
headers) {
2050 includes <<
"#include \"" << header <<
"\"\n";
2054 return result == cling::Interpreter::CompilationResult::kSuccess;
2063#ifdef __INTEL_COMPILER
2076#ifdef __GNUC_MINOR__
2092#ifdef _STLPORT_VERSION
2131#if defined(_WIN64) && defined(_DEBUG)
2143 return llvm::sys::path::filename(path).str();
2153 if (std::string::npos != pos) {
2154 dirname.assign(path.begin(), path.begin() + pos + 1);
2222 const cling::Interpreter &
interp)
2224 if (!
decls.empty()) {
2231 names.push_back(
d->getQualifiedNameAsString());
2252 const std::list<std::string> &
nsNames,
2253 const std::list<std::string> &
tdNames,
2254 const std::list<std::string> &
enNames,
2255 const std::list<std::string> &
varNames,
2289 rootmapFile <<
"class " << className << std::endl;
2296 if (className.find(
"<") != std::string::npos)
continue;
2300 auto &header =
headers.front();
2321 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2330 rootmapFile <<
"# List of selected enums and outer classes\n";
2357 if (
foundNsPos == std::string::npos)
return {
"",
""};
2413 std::list<std::string> &
el_list,
2414 std::unordered_set<std::string> &
el_set)
2421 if (
el_set.insert(tmp).second && !tmp.empty()) {
2472 std::cerr <<
"FATAL: A class with normalized name " <<
normalizedName
2473 <<
" was already selected. This means that two different instances of"
2474 <<
" clang::RecordDecl had the same name, which is not possible."
2475 <<
" This can be a hint of a serious problem in the class selection."
2476 <<
" In addition, the generated dictionary would not even compile.\n";
2490 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl)) {
2532 !llvm::isa<clang::ClassTemplateSpecializationDecl>(
rDecl) &&
2586 if (clang::CXXRecordDecl *
CXXRD =
2587 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2599 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2602 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2605 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2621 if (
interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2622 "#include \"TFile.h\"\n"
2623 "#include \"TObjArray.h\"\n"
2624 "#include \"TVirtualArray.h\"\n"
2625 "#include \"TStreamerElement.h\"\n"
2626 "#include \"TProtoClass.h\"\n"
2627 "#include \"TBaseClass.h\"\n"
2628 "#include \"TListOfDataMembers.h\"\n"
2629 "#include \"TListOfEnums.h\"\n"
2630 "#include \"TListOfEnumsWithLock.h\"\n"
2631 "#include \"TDataMember.h\"\n"
2632 "#include \"TEnum.h\"\n"
2633 "#include \"TEnumConstant.h\"\n"
2634 "#include \"TDictAttributeMap.h\"\n"
2635 "#include \"TMessageHandler.h\"\n"
2636 "#include \"TArray.h\"\n"
2637 "#include \"TRefArray.h\"\n"
2638 "#include \"root_std_complex.h\"\n")
2639 != cling::Interpreter::kSuccess)
2675 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2676 if (
nsName.find(
"(anonymous)") == std::string::npos)
2681 if (!
selClass.GetRecordDecl()->isCompleteDefinition()) {
2685 if (
selClass.RequestOnlyTClass()) {
2693 if (clang::CXXRecordDecl *
CXXRD =
2694 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(
selClass.GetRecordDecl()))) {
2698 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2706 }
else if (
CRD->getName() ==
"RVec") {
2707 static const clang::DeclContext *
vecOpsDC =
nullptr;
2709 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2710 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2732 if (!
selClass.GetRecordDecl()->isCompleteDefinition() ||
selClass.RequestOnlyTClass()) {
2736 const clang::CXXRecordDecl *
cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2748 if (!
selClass.GetRecordDecl()->isCompleteDefinition() || !
selClass.RequestOnlyTClass()) {
2752 const clang::CXXRecordDecl *
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(
selClass.GetRecordDecl());
2798 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2799 <<
"#define R__DICTIONARY_FILENAME " <<
main_dictname << std::endl
2802 <<
"#define R__NO_DEPRECATION" << std::endl
2807 <<
"\n/*******************************************************************/\n"
2808 <<
"#include <stddef.h>\n"
2809 <<
"#include <stdio.h>\n"
2810 <<
"#include <stdlib.h>\n"
2811 <<
"#include <string.h>\n"
2812 <<
"#include <assert.h>\n"
2813 <<
"#define G__DICTIONARY\n"
2814 <<
"#include \"ROOT/RConfig.hxx\"\n"
2815 <<
"#include \"TClass.h\"\n"
2816 <<
"#include \"TDictAttributeMap.h\"\n"
2817 <<
"#include \"TInterpreter.h\"\n"
2818 <<
"#include \"TROOT.h\"\n"
2819 <<
"#include \"TBuffer.h\"\n"
2820 <<
"#include \"TMemberInspector.h\"\n"
2821 <<
"#include \"TInterpreter.h\"\n"
2822 <<
"#include \"TVirtualMutex.h\"\n"
2823 <<
"#include \"TError.h\"\n\n"
2824 <<
"#ifndef G__ROOT\n"
2825 <<
"#define G__ROOT\n"
2827 <<
"#include \"RtypesImp.h\"\n"
2828 <<
"#include \"TIsAProxy.h\"\n"
2829 <<
"#include \"TFileMergeInfo.h\"\n"
2830 <<
"#include <algorithm>\n"
2831 <<
"#include \"TCollectionProxyInfo.h\"\n"
2832 <<
"/*******************************************************************/\n\n"
2833 <<
"#include \"TDataMember.h\"\n\n";
2840 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2841 <<
"namespace std {} using namespace std;\n\n";
2850 dictStream <<
"// Header files passed as explicit arguments\n"
2852 <<
"// Header files passed via #pragma extra_include\n"
2859#if defined(R__IOSSIM) || defined(R__IOS)
2920 for (
unsigned int i = 0; i < m_size; ++i) {
2921 const char *
tmpName = m_tempNames[i].c_str();
2928 if (
ifile.is_open())
2930 if (0 != std::remove(
tmpName)) {
2943 for (
unsigned int i = 0; i < m_size; ++i) {
2944 const char *
tmpName = m_tempNames[i].c_str();
2945 const char *
name = m_names[i].c_str();
2952 if (
ifile.is_open())
2960 llvm::sys::fs::remove(
tmpName);
2976 size_t i = std::distance(m_tempNames.begin(),
2977 find(m_tempNames.begin(), m_tempNames.end(),
tmpFileName));
2978 if (i == m_tempNames.size())
return m_emptyString;
2985 std::cout <<
"Restoring files in temporary file catalog:\n";
2986 for (
unsigned int i = 0; i < m_size; ++i) {
2987 std::cout << m_tempNames[i] <<
" --> " << m_names[i] << std::endl;
3019 static const std::string pattern(
"-Wno-");
3021 if (arg.find(pattern) != 0)
3032 cling::Interpreter &
interp)
3057 if (
qt.isNull())
return qt;
3059 while (
thisQt->isPointerType() ||
3060 thisQt->isReferenceType()) {
3071 const cling::Interpreter &
interp,
3074 std::list<std::string>
headers;
3077 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
3084 if (
const clang::ClassTemplateSpecializationDecl *
tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&
rcd)) {
3087 for (
auto &
tArg :
tsd->getTemplateArgs().asArray()) {
3088 if (clang::TemplateArgument::ArgKind::Type !=
tArg.getKind())
continue;
3109 if (
const clang::FieldDecl *
fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*
declIt)) {
3122 for (
auto & fPar :
methodIt->parameters()) {
3157 if (!
dclCtxt->isStdNamespace()){
3177 if (
argKind != clang::TemplateArgument::Type){
3178 if (
argKind == clang::TemplateArgument::Integral)
continue;
3185 if (
isPOD)
continue;
3210 const cling::Interpreter &
interp)
3213 std::unordered_set<std::string> buffer;
3218 if (
const clang::CXXRecordDecl *
cxxRcd =
3219 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
annotatedRcd.GetRecordDecl())) {
3225 headers.remove_if([&buffer](
const std::string & s) {
3226 return !buffer.insert(s).second;
3239 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(
cxxRcd)){
3248 if (clang::CXXRecordDecl *
cxxRcd =
tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3255 headers.remove_if([&buffer](
const std::string & s) {
3256 return !buffer.insert(s).second;
3287 const cling::Interpreter &
interp)
3295 std::unordered_set<std::string>
fwdDecls;
3338 std::cout <<
"Logs from forward decl printer: \n"
3369 std::cout <<
"Class-headers Mapping:\n";
3385 std::cout << std::endl;
3412 static const std::vector<std::string>
namePrfxes {
3417 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3435 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3449 std::cerr <<
"Error: Class " <<
clName <<
" has been selected but "
3450 <<
"currently the support for its I/O is not yet available. Note that "
3451 <<
clName <<
", even if not selected, will be available for "
3452 <<
"interpreted code.\n";
3456 std::cerr <<
"Error: It is not necessary to explicitly select class "
3457 <<
clName <<
". I/O is supported for it transparently.\n";
3469 bool isLocked =
false;
3472 InterpreterCallbacks(
interp),
3478 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3479 clang::OptionalFileEntryRef , llvm::StringRef ,
3480 llvm::StringRef ,
const clang::Module * ,
3481 clang::SrcMgr::CharacteristicKind )
override
3483 if (isLocked)
return;
3496 fFilesIncludedByLinkdef.clear();
3516 using namespace clang;
3517 if (llvm::StringRef(M->Name).ends_with(
"ACLiC_dict")) {
3523 assert(M &&
"Must have module Core");
3530 llvm::cl::desc(
"Allow implicit build of system modules."),
3532static llvm::cl::list<std::string>
3535 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3538static llvm::cl::opt<std::string>
3540 llvm::cl::desc(
"<output dictionary file>"),
3572 using namespace clang::diag;
3579 const clang::Module *
module = nullptr;
3582 const auto &ID =
Info.getID();
3585 module = fMap.findModule(moduleName);
3591 "Couldn't find module %s in the available modulemaps. This"
3592 "prevents us from correctly diagnosing wrongly built modules.\n",
3623 "Building module '%s' implicitly. If '%s' requires a \n"
3624 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3625 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3635 DiagnosticConsumer::clear();
3641 DiagnosticConsumer::BeginSourceFile(
LangOpts,
PP);
3646 fChild->EndSourceFile();
3647 DiagnosticConsumer::EndSourceFile();
3653 DiagnosticConsumer::finish();
3660#if defined(_WIN32) && defined(_MSC_VER)
3677static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3679static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3690static llvm::cl::opt<VerboseLevel>
3692 llvm::cl::values(
clEnumVal(
v,
"Show errors."),
3701static llvm::cl::opt<bool>
3702gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3705static llvm::cl::opt<bool>
3706gOptReflex(
"reflex", llvm::cl::desc(
"Behave internally like genreflex."),
3708static llvm::cl::opt<bool>
3709gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3712static llvm::cl::opt<std::string>
3714 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3717static llvm::cl::opt<bool>
3719 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3722static llvm::cl::opt<bool>
3723gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3725static llvm::cl::opt<bool>
3726gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3728static llvm::cl::list<std::string>
3730 llvm::cl::desc(
"Generate rootmap file."),
3732static llvm::cl::opt<std::string>
3734 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3736static llvm::cl::opt<bool>
3738 llvm::cl::desc(
"Generate a C++ module."),
3740static llvm::cl::list<std::string>
3742 llvm::cl::desc(
"Specify a C++ modulemap file."),
3745static llvm::cl::opt<bool>
3747 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3749static llvm::cl::opt<bool>
3751 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3753static llvm::cl::opt<bool>
3755 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3757static llvm::cl::opt<bool>
3759 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3761static llvm::cl::opt<bool>
3763 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3764information and another the interactivity support."),
3766static llvm::cl::opt<bool>
3769 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3771static llvm::cl::opt<std::string>
3773 llvm::cl::desc(
"The path to the library of the built dictionary."),
3775static llvm::cl::list<std::string>
3777 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3779static llvm::cl::list<std::string>
3781 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3785static llvm::cl::opt<bool>
3787 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3795static llvm::cl::opt<bool>
3798 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3800static llvm::cl::opt<bool>
3802 llvm::cl::desc(
"Check the selection syntax only."),
3804static llvm::cl::opt<bool>
3806 llvm::cl::desc(
"Fail if there are warnings."),
3808static llvm::cl::opt<bool>
3810 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3812static llvm::cl::opt<std::string>
3814 llvm::cl::desc(
"Specify an isysroot."),
3816 llvm::cl::init(
"-"));
3817static llvm::cl::list<std::string>
3819 llvm::cl::desc(
"Specify an include path."),
3821static llvm::cl::list<std::string>
3823 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3825static llvm::cl::list<std::string>
3827 llvm::cl::desc(
"Specify a system include path."),
3829static llvm::cl::list<std::string>
3831 llvm::cl::desc(
"Specify defined macros."),
3833static llvm::cl::list<std::string>
3835 llvm::cl::desc(
"Specify undefined macros."),
3837static llvm::cl::list<std::string>
3839 llvm::cl::desc(
"Specify compiler diagnostics options."),
3842static llvm::cl::list<std::string>
3844 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file | selection xml file>"),
3846static llvm::cl::list<std::string>
3848 llvm::cl::desc(
"Consumes all unrecognized options."),
3851static llvm::cl::SubCommand
3854static llvm::cl::list<std::string>
3856 llvm::cl::desc(
"Consumes options and sends them to cling."),
3885 for (
const std::string &header :
modGen.GetHeaders()) {
3890 clang::ConstSearchDirIterator *
CurDir =
nullptr;
3892 header, clang::SourceLocation(),
3895 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef, clang::DirectoryEntryRef>>(),
3934 clang::HeaderSearch &
headerSearch =
CI->getPreprocessor().getHeaderSearchInfo();
3938 clang::Module *
module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3954 msgStream <<
"after creating module \"" <<
module->Name << "\" ";
3955 if (!
module->PresumedModuleMapFile.empty())
3956 msgStream <<
"using modulemap \"" <<
module->PresumedModuleMapFile << "\" ";
3957 msgStream <<
"the following headers are not part of that module:\n";
3961 msgStream <<
" (already part of module \"" <<
H[1] <<
"\")";
3977 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3987 [](
const std::array<std::string, 2>&
HdrMod) { return HdrMod[0];});
4025 llvm::PrettyStackTraceProgram
X(
argc,
argv);
4028#if defined(R__WIN32) && !defined(R__WINGCC)
4049 auto &
opts = llvm::cl::getRegisteredOptions();
4052 llvm::cl::desc(
"Alias for -help"),
4053 llvm::cl::aliasopt(*
optHelp));
4055 llvm::cl::desc(
"Alias for -help"),
4056 llvm::cl::aliasopt(*
optHelp));
4058 llvm::cl::ParseCommandLineOptions(
argc,
argv,
"rootcling");
4083 return interp->getDiagnostics().hasFatalErrorOccurred();
4100 llvm::cl::PrintHelpMessage();
4115 if ((fp =
fopen(
filein.c_str(),
"r")) ==
nullptr) {
4143 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4144 llvm::cl::PrintHelpMessage();
4156 std::list<std::string>
diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4162 if (GetErrorIgnoreLevel() >
kWarning)
4164 GetWarningsAreErrors() =
true;
4178 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4214 std::vector<std::string>
pcmArgs;
4228 [&](
const std::string& path){
4229 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4237 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(
etcDir));
4244 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4245#elif defined(R__WIN32)
4246 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4253 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4261 clingArgs.push_back(
"-fmodules-embed-all-files");
4325 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4326 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4327 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4328 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4330 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4331 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4335 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4337 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4339 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4340 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4341 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4342 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4343 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4344 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4345 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4347 remove((
moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4362 std::cerr <<
"Argument \""<<
clingArg <<
"\" is not a supported cling argument. "
4363 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4371 cling::Interpreter*
interpPtr =
nullptr;
4399 clang::CompilerInstance *
CI =
interp.getCI();
4401 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4402 CI->getSourceManager().setAllFilesAreTransient(
true);
4404 clang::Preprocessor &
PP =
CI->getPreprocessor();
4414 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4425 interp.DumpIncludePath();
4430 interp.printIncludedFiles(llvm::outs());
4431 llvm::outs() <<
"\n\n";
4432 llvm::outs().flush();
4436 =
interp.getCI()->getASTContext().getLangOpts();
4437#define LANGOPT(Name, Bits, Default, Description) \
4438 ROOT::TMetaUtils::Info(nullptr, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4439#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4440#include "clang/Basic/LangOptions.def"
4444 interp.getOptions().ErrorOut =
true;
4445 interp.enableRawInput(
true);
4449 if (
DepMod.ends_with(
"_rdict.pcm")) {
4456 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
4466 if (
interp.declare(
"#include <assert.h>\n"
4467 "#include \"Rtypes.h\"\n"
4468 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4476 if (
interp.declare(
"#include <string>\n"
4477 "#include <RtypesCore.h>\n"
4478 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4574 std::stringstream res;
4575 const char*
delim=
"\n";
4578 std::ostream_iterator<std::string>(res,
delim));
4579 if (
interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4588 clang::PragmaNamespace(
pragma) {}
4589 void HandlePragma(clang::Preprocessor &
PP,
4591 clang::Token &
tok)
override {
4592 PP.DiscardUntilEndOfDirective();
4676 if (
dh != std::string::npos) {
4740 if (file.is_open()) {
4753 clingArgs.push_back(
"-Ietc/cling/cint");
4773 if (file.is_open()) {
4814 <<
"#include \"TVirtualObject.h\"\n"
4815 <<
"#include <vector>\n"
4816 <<
"#include \"TSchemaHelper.h\"\n\n";
4856 scan.
Scan(
CI->getASTContext());
4879 if (
annRcd.RequestNoInputOperator()) {
5042 [](
const std::string &
a,
const std::string &
b) -> std::string {
5043 if (a.empty()) return b;
5044 else return a +
" " + b;
5074 std::list<std::string>
nsNames;
5117 cling::Interpreter::PushTransactionRAII
RAII(&
interp);
5118 CI->getSema().getASTConsumer().HandleTranslationUnit(
CI->getSema().getASTContext());
5154 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5168 for (
int i = 1; i <
argc; ++i) {
5171 args.push_back(
argv[i]);
5181 std::cout <<
"Args: \n";
5182 for (std::vector<std::string>::iterator it = args.begin();
5183 it < args.end(); ++it) {
5184 std::cout << i <<
") " << *it << std::endl;
5198 if (std::string::npos !=
result) {
5210 const unsigned int size(str.size());
5211 char *
a =
new char[
size + 1];
5245 const std::string &
optName =
"")
5257 const std::string &
optName =
"")
5274 const std::vector<std::string> &
pcmsNames,
5275 const std::vector<std::string> &
includes,
5278 const std::vector<std::string> &
warnings,
5316 "*** genreflex: No rootmap lib and several header specified!\n");
5409 for (
int i = 0; i <
argc; i++) {
5415 std::cout <<
cmd << std::endl;
5424 for (
int i = 0; i <
argc; i++)
5439 const std::vector<std::string> &
pcmsNames,
5440 const std::vector<std::string> &
includes,
5443 const std::vector<std::string> &
warnings,
5468 for (
unsigned int i = 0; i <
headersNames.size(); ++i) {
5510 std::vector<std::string> &values)
5515 values.reserve(
nVals);
5520 << opt->arg << std::endl;
5522 values.push_back(opt->arg);
5537 "*** genereflex: %s is not supported anymore.\n",
5630 "********************************************************************************\n"
5631 "* The genreflex utility does not allow to generate C++ modules containing *\n"
5632 "* reflection information required at runtime. Please use rootcling instead *\n"
5633 "* To print the rootcling invocation that corresponds to the current genreflex *\n"
5634 "* invocation please use the --print-rootcling-invocation flag. *\n"
5635 "********************************************************************************\n"
5637 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5638 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5642 "--print-rootcling-invocation\n"
5643 " Print to screen the rootcling invocation corresponding to the current \n"
5644 " genreflex invocation.\n";
5647 "-s, --selection_file\tSelection filename\n"
5648 " Class selection file to specify for which classes the dictionary\n"
5649 " will be generated. The final set can be crafted with exclusion and\n"
5650 " exclusion rules.\n"
5651 " Properties can be specified. Some have special meaning:\n"
5652 " - name [string] name of the entity to select with an exact matching\n"
5653 " - pattern [string] name with wildcards (*) to select entities\n"
5654 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5655 " file where the C++ entities reside and not to C++ entities themselves.\n"
5656 " - transient/persistent [string: true/false] The fields to which they are\n"
5657 " applied will not be persistified if requested.\n"
5658 " - comment [string]: what you could write in code after an inline comment\n"
5659 " without \"//\". For example comment=\"!\" or \"||\".\n"
5660 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5661 " Default value is 'false'\n"
5662 " - rntupleStreamerMode [true/false]: enforce streamed or native writing for RNTuple.\n"
5663 " If unset, RNTuple stores classes in split mode or fails if the class cannot be split.\n"
5664 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5665 " to 'true'. Default value is 'false'\n"
5669 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5670 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5671 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5672 " [noInputOperator=\"true/false\"]\n"
5673 " [rntupleStreamerMode=\"true/false\"] />\n"
5674 " <class name=\"classname\" >\n"
5675 " <field name=\"m_transient\" transient=\"true\"/>\n"
5676 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5677 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5678 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5680 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5681 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5682 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5685 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5686 " <method name=\"unwanted\" />\n"
5691 " If no selection file is specified, the class with the filename without\n"
5692 " extension will be selected, i.e. myClass.h as argument without any\n"
5693 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5696 "-o, --output\tOutput filename\n"
5697 " Output file name. If an existing directory is specified instead of a file,\n"
5698 " then a filename will be built using the name of the input file and will\n"
5699 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5700 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5701 " have unique names.\n";
5705 "-l, --library\tTarget library\n"
5706 " The flag -l must be followed by the name of the library that will\n"
5707 " contain the object file corresponding to the dictionary produced by\n"
5708 " this invocation of genreflex.\n"
5709 " The name takes priority over the one specified for the rootmapfile.\n"
5710 " The name influences the name of the created pcm:\n"
5711 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5712 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5713 " Any \"liblib\" occurence is transformed in the expected \"lib\".\n"
5714 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5715 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5718 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5719 " This file lists the autoload keys. For example classes for which the\n"
5720 " reflection information is provided.\n"
5721 " The format of the rootmap is the following:\n"
5722 " - Forward declarations section\n"
5723 " - Libraries sections\n"
5724 " Rootmaps can be concatenated together, for example with the cat util.\n"
5725 " In order for ROOT to pick up the information in the rootmaps, they\n"
5726 " have to be located in the library path and have the .rootmap extension.\n"
5727 " An example rootmap file could be:\n"
5729 " template <class T> class A;\n"
5730 " [ libMyLib.so ]\n"
5731 " class A<double>\n"
5737 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5753 "",
"print-rootcling-invocation",
5779 "--multiDict\tSupport for many dictionaries in one library\n"
5780 " Form correct pcm names if multiple dictionaries will be in the same\n"
5781 " library (needs target library switch. See its documentation).\n"
5788 "" ,
"noGlobalUsingStd" ,
5790 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5791 " All header files must have sumbols from std:: namespace fully qualified\n"
5797 "s" ,
"selection_file" ,
5813 "" ,
"rootmap-lib" ,
5821 "" ,
"interpreteronly",
5823 "--interpreteronly\tDo not generate I/O related information.\n"
5824 " Generate minimal dictionary required for interactivity.\n"
5832 "--split\tSplit the dictionary\n"
5833 " Split in two the dictionary, isolating the part with\n"
5834 " ClassDef related functions in a separate file.\n"
5842 "-m \tPcm file loaded before any header (option can be repeated).\n"
5850 "-v, --verbose\tPrint some debug information.\n"
5858 "--debug\tPrint all debug information.\n"
5866 "--quiet\tPrint only warnings and errors (default).\n"
5874 "--silent\tPrint no information at all.\n"
5880 "" ,
"writeEmptyPCM",
5882 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5890 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5899 "--help\tPrint usage and exit.\n"
5905 "",
"fail_on_warnings",
5907 "--fail_on_warnings\tFail on warnings and errors.\n"
5913 "",
"selSyntaxOnly",
5915 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5921 "" ,
"noIncludePaths",
5923 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5962 "" ,
"no_membertypedefs" ,
5970 "" ,
"no_templatetypedefs" ,
5975 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
5989 std::vector<ROOT::option::Option> options(
stats.options_max);
5990 std::vector<ROOT::option::Option> buffer(
stats.buffer_max);
5996 if (parse.
error()) {
6032 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
6057 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6077 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6229 if (std::string::npos !=
exeName.find(
"genreflex"))
6237 ROOT::TMetaUtils::Info(
nullptr,
"Problems have been detected during the generation of the dictionary.\n");
Select classes and assign properties using C++ syntax.
The file contains utilities which are foundational and could be used across the core component of ROO...
This is the only file required to use The Lean Mean C++ Option Parser.
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Basic types used by ROOT and required by TInterpreter.
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
std::unordered_map< std::string, std::string > AttributesMap_t
Custom diag client for clang that verifies that each implicitly build module is a system module.
void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override
~CheckModuleBuildClient() override
CheckModuleBuildClient(clang::DiagnosticConsumer *Child, bool OwnsChild, clang::ModuleMap &Map)
clang::DiagnosticConsumer * fChild
bool IncludeInDiagnosticCounts() const override
void EndSourceFile() override
void BeginSourceFile(const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) override
const_iterator begin() const
const_iterator end() const
A parsed option from the command line together with its argument if it has one.
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
bool error()
Returns true if an unrecoverable error occurred while parsing options.
void Scan(const clang::ASTContext &C)
std::vector< ROOT::TMetaUtils::AnnotatedRecordDecl > ClassColl_t
const DeclsSelRulesMap_t & GetDeclsSelRulesMap() const
FunctionColl_t fSelectedFunctions
std::vector< const clang::FunctionDecl * > FunctionColl_t
NamespaceColl_t fSelectedNamespaces
TypedefColl_t fSelectedTypedefs
DeclCallback SetRecordDeclCallback(DeclCallback callback)
Set the callback to the RecordDecl and return the previous one.
std::map< const clang::Decl *, const BaseSelectionRule * > DeclsSelRulesMap_t
EnumColl_t fSelectedEnums
std::vector< const clang::TypedefNameDecl * > TypedefColl_t
std::vector< const clang::VarDecl * > VariableColl_t
static bool GetDeclQualName(const clang::Decl *D, std::string &qual_name)
VariableColl_t fSelectedVariables
std::vector< const clang::EnumDecl * > EnumColl_t
ClassColl_t fSelectedClasses
The class representing the collection of selection rules.
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
~TRootClingCallbacks() 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.
Namespace for new ROOT classes and functions.
@ 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 > 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.