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>
63#include "cling/Interpreter/Interpreter.h"
64#include "cling/Interpreter/InterpreterCallbacks.h"
65#include "cling/Interpreter/LookupHelper.h"
66#include "cling/Interpreter/Value.h"
67#include "clang/AST/CXXInheritance.h"
68#include "clang/Basic/Diagnostic.h"
69#include "clang/Frontend/CompilerInstance.h"
70#include "clang/Frontend/FrontendActions.h"
71#include "clang/Frontend/FrontendDiagnostic.h"
72#include "clang/Lex/HeaderSearch.h"
73#include "clang/Lex/Preprocessor.h"
74#include "clang/Lex/ModuleMap.h"
75#include "clang/Lex/Pragma.h"
76#include "clang/Sema/Sema.h"
77#include "clang/Serialization/ASTWriter.h"
78#include "cling/Utils/AST.h"
80#include "llvm/ADT/StringRef.h"
82#include "llvm/Support/CommandLine.h"
83#include "llvm/Support/Path.h"
84#include "llvm/Support/PrettyStackTrace.h"
85#include "llvm/Support/Signals.h"
109#include <mach-o/dyld.h>
114#define strcasecmp _stricmp
115#define strncasecmp _strnicmp
141static llvm::cl::opt<bool>
143 llvm::cl::desc(
"Deprecated. Similar to -f but it ignores the dictionary generation. \
144When -r is present rootcling becomes a tool to generate rootmaps (and capability files)."),
164static void EmitTypedefs(
const std::vector<const clang::TypedefNameDecl *> &tdvec)
168 for (
const auto td : tdvec)
171static void EmitEnums(
const std::vector<const clang::EnumDecl *> &enumvec)
175 for (
const auto en : enumvec) {
177 if (clang::isa<clang::TranslationUnitDecl>(en->getDeclContext())
178 || clang::isa<clang::LinkageSpecDecl>(en->getDeclContext())
179 || clang::isa<clang::NamespaceDecl>(en->getDeclContext()))
189 static std::string exepath;
192 exepath = _dyld_get_image_name(0);
194#if defined(__linux) || defined(__linux__)
195 char linkname[PATH_MAX];
201 snprintf(linkname, PATH_MAX,
"/proc/%i/exe", pid);
202 int ret = readlink(linkname, buf, 1024);
203 if (ret > 0 && ret < 1024) {
209 char *buf =
new char[MAX_MODULE_NAME32 + 1];
210 ::GetModuleFileName(NULL, buf, MAX_MODULE_NAME32 + 1);
212 while ((
p = strchr(
p,
'\\')))
218 return exepath.c_str();
224 const cling::Interpreter &interp)
232 const std::list<VariableSelectionRule> &fieldSelRules)
240 if (fieldSelRules.empty())
return;
242 clang::ASTContext &C = decl.getASTContext();
244 const std::string declName(decl.getNameAsString());
246 for (std::list<VariableSelectionRule>::const_iterator it = fieldSelRules.begin();
247 it != fieldSelRules.end(); ++it) {
248 if (! it->GetAttributeValue(propNames::name, varName))
continue;
249 if (declName == varName) {
252 BaseSelectionRule::AttributesMap_t::iterator iter;
253 std::string userDefinedProperty;
254 for (iter = attrMap.begin(); iter != attrMap.end(); ++iter) {
255 const std::string &
name = iter->first;
256 const std::string &
value = iter->second;
258 if (
name == propNames::name)
continue;
263 if (
name == propNames::iotype &&
264 (decl.getType()->isArrayType() || decl.getType()->isPointerType())) {
265 const char *msg =
"Data member \"%s\" is an array or a pointer. "
266 "It is not possible to assign to it the iotype \"%s\". "
267 "This transformation is possible only with data members "
268 "which are not pointers or arrays.\n";
270 msg, varName.c_str(),
value.c_str());
278 if (
name == propNames::comment) {
279 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
value));
283 if ((
name == propNames::transient &&
value ==
"true") ||
284 (
name == propNames::persistent &&
value ==
"false")) {
285 userDefinedProperty = propNames::comment + propNames::separator +
"!";
289 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C,
"!"));
294 userDefinedProperty =
name + propNames::separator +
value;
297 decl.addAttr(clang::AnnotateAttr::CreateImplicit(C, userDefinedProperty));
308 cling::Interpreter &interpreter,
316 using namespace clang;
317 SourceLocation commentSLoc;
318 llvm::StringRef comment;
320 ASTContext &C = CXXRD.getASTContext();
323 clang::Decl *declBaseClassPtr =
static_cast<clang::Decl *
>(&CXXRD);
324 auto declSelRulePair = declSelRulesMap.find(declBaseClassPtr->getCanonicalDecl());
325 if (declSelRulePair == declSelRulesMap.end()){
326 const std::string thisClassName(CXXRD.getName());
327 ROOT::TMetaUtils::Error(
"AnnotateDecl",
"Cannot find class %s in the list of selected classes.\n",thisClassName.c_str());
332 if (thisClassBaseSelectionRule) {
335 BaseSelectionRule::AttributesMap_t::iterator iter;
336 std::string userDefinedProperty;
338 const std::string &
name =
attr.first;
343 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, userDefinedProperty));
350 for (CXXRecordDecl::decl_iterator
I = CXXRD.decls_begin(),
351 E = CXXRD.decls_end();
I != E; ++
I) {
355 if (!(*I)->isImplicit()
356 && (isa<CXXMethodDecl>(*
I) || isa<FieldDecl>(*
I) || isa<VarDecl>(*
I))) {
360 if (isClassDefMacro) {
361 while (isa<NamedDecl>(*
I) && cast<NamedDecl>(*I)->getName() !=
"DeclFileLine") {
367 if (comment.size()) {
369 if (isClassDefMacro) {
370 CXXRD.addAttr(AnnotateAttr::CreateImplicit(C, comment.str()));
371 }
else if (!isGenreflex) {
377 (*I)->addAttr(AnnotateAttr::CreateImplicit(C, comment.str()));
382 if (isGenreflex && thisClassSelectionRule !=
nullptr) {
386 if (FieldDecl *fieldDecl = dyn_cast<FieldDecl>(*
I)) {
400 llvm::APInt
len = arrayType->getSize();
401 while (
const clang::ConstantArrayType *subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual())) {
402 len *= subArrayType->getSize();
403 arrayType = subArrayType;
405 return len.getLimitedValue();
411 const cling::Interpreter &interp)
413 static const clang::CXXRecordDecl *TObject_decl
416 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
423 const cling::Interpreter &interp)
425 static const clang::CXXRecordDecl *TObject_decl
438 return (0 == strcasecmp(
filename + (
len - xmllen),
".xml"));
464 if (exepath && *exepath) {
466 char *ep =
new char[PATH_MAX];
467 if (!realpath(exepath, ep)) {
468 fprintf(stderr,
"rootcling: error getting realpath of rootcling!");
469 strlcpy(ep, exepath, PATH_MAX);
472 int nche = strlen(exepath) + 1;
473 char *ep =
new char[nche];
474 strlcpy(ep, exepath, nche);
478 if ((s = strrchr(ep,
'/'))) {
480 int removesubdirs = 2;
481 if (!strncmp(s + 1,
"rootcling_stage1.exe", 20)) {
485 }
else if (!strncmp(s + 1,
"rootcling_stage1", 16)) {
490 for (
int i = 1; s && i < removesubdirs; ++i) {
492 s = strrchr(ep,
'/');
506 int ncha = strlen(ep) + 10;
507 char *env =
new char[ncha];
508 snprintf(env, ncha,
"ROOTSYS=%s", ep);
529 const char *expectedTokens[],
530 size_t *end =
nullptr)
533 if (
line[0] !=
'#')
return false;
535 for (
const char **iToken = expectedTokens; *iToken; ++iToken) {
536 while (isspace(
line[pos])) ++pos;
537 size_t lenToken = strlen(*iToken);
538 if (
line.compare(pos, lenToken, *iToken)) {
557 if (recordDecl->hasOwningModule()) {
558 clang::Module *M = recordDecl->getOwningModule()->getTopLevelModule();
561 std::string qual_name;
567 if (need.length() &&
gLibsNeeded.find(need) == string::npos) {
576 if (classname.find(
':') == std::string::npos)
return;
579 int slen = classname.size();
580 for (
int k = 0; k < slen; ++k) {
581 if (classname[k] ==
':') {
582 if (k + 1 >= slen || classname[k + 1] !=
':') {
587 string base = classname.substr(0, k);
592 autoloads[base] =
"";
596 }
else if (classname[k] ==
'<') {
608 std::string classname;
612 if (
line.find(
"Library.") != 0)
continue;
614 int pos =
line.find(
":", 8);
615 classname =
line.substr(8, pos - 8);
621 while (
line[0] ==
' ')
line.replace(0, 1,
"");
625 if (classname ==
"ROOT::TImpProxy") {
629 autoloads[classname] =
line;
644 const std::unordered_map<char, unsigned int> keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
647 if (
line ==
"{ decls }") {
649 if (
line[0] ==
'[')
break;
652 const char firstChar =
line[0];
653 if (firstChar ==
'[') {
655 libs =
line.substr(1,
line.find(
']') - 1);
656 while (libs[0] ==
' ') libs.replace(0, 1,
"");
657 }
else if (0 != keyLenMap.count(firstChar)) {
658 unsigned int keyLen = keyLenMap.at(firstChar);
659 keyname =
line.substr(keyLen,
line.length() - keyLen);
661 autoloads[keyname] = libs;
671void LoadLibraryMap(
const std::string &fileListName, map<string, string> &autoloads)
673 std::ifstream filelist(fileListName.c_str());
680 if (llvm::sys::fs::is_directory(
filename))
continue;
686 bool new_format = (
line[0] ==
'[' ||
line[0] ==
'{') ;
688 file.seekg(0, std::ios::beg);
709 const string &fullname,
710 const clang::RecordDecl *cl,
711 cling::Interpreter &interp)
714 const clang::FunctionDecl *method
719 clang::TranslationUnitDecl *TU =
720 cl->getASTContext().getTranslationUnitDecl();
724 bool has_input_error =
false;
725 if (method !=
nullptr && (method->getAccess() == clang::AS_public || method->getAccess() == clang::AS_none)) {
727 if (strstr(
filename.c_str(),
"TBuffer.h") !=
nullptr ||
728 strstr(
filename.c_str(),
"Rtypes.h") !=
nullptr) {
730 has_input_error =
true;
733 has_input_error =
true;
735 if (has_input_error) {
737 const char *maybeconst =
"";
738 const char *mayberef =
"&";
739 if (
what[strlen(
what) - 1] ==
'<') {
740 maybeconst =
"const ";
744 "in this version of ROOT, the option '!' used in a linkdef file\n"
745 " implies the actual existence of customized operators.\n"
746 " The following declaration is now required:\n"
747 " TBuffer &%s(TBuffer &,%s%s *%s);\n",
what, maybeconst, fullname.c_str(), mayberef);
749 return has_input_error;
761 int ncha = fullname.length() + 13;
762 char *
proto =
new char[ncha];
774 return has_input_error;
780bool CheckClassDef(
const clang::RecordDecl &cl,
const cling::Interpreter &interp)
786 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
790 bool isAbstract = clxx->isAbstract();
793 std::string qualName;
795 const char *qualName_c = qualName.c_str();
797 "because it inherits from TObject but does not "
798 "have its own ClassDef.\n",
811 if (
m.getType().isConstQualified()) {
812 string ret =
"const_cast< ";
815 if (type_name.substr(0,6)==
"const ") {
816 ret += type_name.c_str()+6;
822 ret +=
m.getName().str();
826 return prefix +
m.getName().str();
836 const cling::Interpreter &interp,
838 std::ostream &dictStream)
841 std::string mTypename;
854 if (!clxx || clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
856 const clang::ClassTemplateSpecializationDecl *tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (clxx);
857 if (!tmplt_specialization)
return 0;
863 string fulName1, fulName2;
864 const char *tcl1 =
nullptr, *tcl2 =
nullptr;
865 const clang::TemplateArgument &arg0(tmplt_specialization->getTemplateArgs().get(0));
866 clang::QualType ti = arg0.getAsType();
870 fulName1 = ti.getAsString();
873 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
874 clang::QualType tmplti = arg1.getAsType();
877 fulName2 = tmplti.getAsString();
884 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
890 if (arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
894 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
896 }
else if (
m.getType()->isPointerType()) {
901 dictStream <<
" {" << std::endl;
903 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
908 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
";" << std::endl;
911 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
"[R__l];" << std::endl;
914 dictStream <<
" delete *" << stlName.c_str() <<
";" << std::endl
915 <<
" *" << stlName.c_str() <<
" = new " << stlType.c_str() <<
";" << std::endl
916 <<
" " << stlType.c_str() <<
" &R__stl = **" << stlName.c_str() <<
";" << std::endl;
919 dictStream <<
" delete " << stlName.c_str() <<
"[R__l];" << std::endl
920 <<
" " << stlName.c_str() <<
"[R__l] = new " << stlType.c_str() <<
";" << std::endl
921 <<
" " << stlType.c_str() <<
" &R__stl = *" << stlName.c_str() <<
"[R__l];" << std::endl;
925 dictStream <<
" R__stl.clear();" << std::endl;
928 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() <<
"));" << std::endl
929 <<
" if (R__tcl1==0) {" << std::endl
930 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
931 << fulName1.c_str() <<
"!\");" << std::endl
932 <<
" return;" << std::endl
933 <<
" }" << std::endl;
936 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() <<
"));" << std::endl
937 <<
" if (R__tcl2==0) {" << std::endl
938 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
939 << fulName2.c_str() <<
"!\");" << std::endl
940 <<
" return;" << std::endl
941 <<
" }" << std::endl;
944 dictStream <<
" int R__i, R__n;" << std::endl
945 <<
" R__b >> R__n;" << std::endl;
948 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
950 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
954 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
974 std::string keyName(ti.getAsString());
975 dictStream <<
" typedef " << keyName <<
" Value_t;" << std::endl
976 <<
" std::pair<Value_t const, " << tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
977 <<
" R__stl.insert(R__t3);" << std::endl;
985 dictStream <<
" R__stl.insert(R__t);" << std::endl;
990 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
993 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
998 dictStream <<
" }" << std::endl
999 <<
" }" << std::endl;
1000 if (isArr) dictStream <<
" }" << std::endl;
1006 dictStream <<
" for (Int_t R__l = 0; R__l < " <<
len <<
"; R__l++) {" << std::endl;
1008 dictStream <<
" {" << std::endl;
1011 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
";" << std::endl;
1014 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
"[R__l];" << std::endl;
1017 dictStream <<
" " << stlType.c_str() <<
" &R__stl = **" << stlName.c_str() <<
";" << std::endl;
1020 dictStream <<
" " << stlType.c_str() <<
" &R__stl = *" << stlName.c_str() <<
"[R__l];" << std::endl;
1024 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
1025 <<
" R__b << R__n;" << std::endl
1026 <<
" if(R__n) {" << std::endl;
1029 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() <<
"));" << std::endl
1030 <<
" if (R__tcl1==0) {" << std::endl
1031 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
1032 << fulName1.c_str() <<
"!\");" << std::endl
1033 <<
" return;" << std::endl
1034 <<
" }" << std::endl;
1037 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() <<
"));" << std::endl
1038 <<
" if (R__tcl2==0) {" << std::endl
1039 <<
" Error(\"" << stlName.c_str() <<
"streamer\",\"Missing the TClass object for " << fulName2.c_str() <<
"!\");" << std::endl
1040 <<
" return;" << std::endl
1041 <<
" }" << std::endl;
1044 dictStream <<
" " << stlType.c_str() <<
"::iterator R__k;" << std::endl
1045 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
1047 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
1048 clang::QualType tmplti = arg1.getAsType();
1055 dictStream <<
" }" << std::endl
1056 <<
" }" << std::endl
1057 <<
" }" << std::endl;
1058 if (isArr) dictStream <<
" }" << std::endl;
1070 std::string mTypenameStr;
1074 if (!strcmp(mTypeName,
"string")) {
1076 std::string fieldname =
m.getName().str();
1079 if (
m.getType()->isConstantArrayType()) {
1080 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1081 dictStream <<
"// Array of pointer to std::string are not supported (" << fieldname <<
"\n";
1083 std::stringstream fullIdx;
1084 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1087 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1088 << arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1089 fullIdx <<
"[R__i" << dim <<
"]";
1090 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1093 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1094 << fieldname << fullIdx.str() <<
" = R__str.Data();}" << std::endl;
1097 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1098 if (
m.getType()->isPointerType())
1099 dictStream <<
"if (*" << fieldname <<
") delete *" << fieldname <<
"; (*"
1100 << fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1102 dictStream << fieldname <<
" = R__str.Data(); }" << std::endl;
1106 if (
m.getType()->isPointerType())
1107 dictStream <<
" { TString R__str; if (*" << fieldname <<
") R__str = (*"
1108 << fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1109 else if (
m.getType()->isConstantArrayType()) {
1110 std::stringstream fullIdx;
1111 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1114 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1115 << arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1116 fullIdx <<
"[R__i" << dim <<
"]";
1117 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1120 dictStream <<
" { TString R__str(" << fieldname << fullIdx.str() <<
".c_str()); R__str.Streamer(R__b);}" << std::endl;
1122 dictStream <<
" { TString R__str = " << fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1133 if (
m.getType()->isPointerType()) {
1134 if (
m.getType()->getPointeeType()->isPointerType()) {
1146 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1148 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1150 dictStream <<
"[0]";
1151 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1166 int enclSpaceNesting = 0;
1173 dictStream <<
"#include \"TInterpreter.h\"\n";
1175 dictStream <<
"//_______________________________________"
1176 <<
"_______________________________________" << std::endl;
1177 if (add_template_keyword) dictStream <<
"template <> ";
1178 dictStream <<
"atomic_TClass_ptr " << clsname <<
"::fgIsA(nullptr); // static to hold class pointer" << std::endl
1181 <<
"//_______________________________________"
1182 <<
"_______________________________________" << std::endl;
1183 if (add_template_keyword) dictStream <<
"template <> ";
1184 dictStream <<
"const char *" << clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1185 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1187 dictStream <<
"//_______________________________________"
1188 <<
"_______________________________________" << std::endl;
1189 if (add_template_keyword) dictStream <<
"template <> ";
1190 dictStream <<
"const char *" << clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1191 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1192 <<
"*)nullptr)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1194 <<
"//_______________________________________"
1195 <<
"_______________________________________" << std::endl;
1196 if (add_template_keyword) dictStream <<
"template <> ";
1197 dictStream <<
"int " << clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1198 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1199 <<
"*)nullptr)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1201 <<
"//_______________________________________"
1202 <<
"_______________________________________" << std::endl;
1203 if (add_template_keyword) dictStream <<
"template <> ";
1204 dictStream <<
"TClass *" << clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1208 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1209 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1210 <<
"*)nullptr)->GetClass();" << std::endl
1211 <<
" return fgIsA;\n"
1212 <<
"}" << std::endl << std::endl
1214 <<
"//_______________________________________"
1215 <<
"_______________________________________" << std::endl;
1216 if (add_template_keyword) dictStream <<
"template <> ";
1217 dictStream <<
"TClass *" << clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1219 dictStream <<
" Dictionary();\n";
1221 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1222 dictStream << fullname <<
"*)nullptr)->GetClass(); }" << std::endl;
1224 dictStream <<
" return fgIsA;" << std::endl
1225 <<
"}" << std::endl << std::endl;
1227 while (enclSpaceNesting) {
1228 dictStream <<
"} // namespace " << nsname << std::endl;
1237 cling::Interpreter &interp,
1238 std::ostream &dictStream)
1240 if (cl->isAnonymousNamespace()) {
1252 if (classname !=
"ROOT") {
1256 dictStream <<
" namespace ROOTDict {" << std::endl;
1259 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1263 dictStream <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();" << std::endl;
1264 dictStream << std::endl
1266 <<
" // Function generating the singleton type initializer" << std::endl
1269 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1270 <<
" {" << std::endl
1272 <<
" ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1273 <<
" {" << std::endl
1276 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1278 <<
" instance(\"" << classname.c_str() <<
"\", ";
1281 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1283 dictStream <<
"0 /*version*/, ";
1287 for (
unsigned int i = 0; i <
filename.length(); i++) {
1291 <<
" ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
1295 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1297 dictStream <<
"&" << mappedname.c_str() <<
"_Dictionary, ";
1300 dictStream << 0 <<
");" << std::endl
1302 <<
" return &instance;" << std::endl
1303 <<
" }" << std::endl
1304 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1305 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1306 <<
" // Static variable to force the class initialization" << std::endl
1308 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1309 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1312 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1313 <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary() {" << std::endl
1314 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1315 <<
" }" << std::endl << std::endl;
1318 dictStream <<
" }" << std::endl;
1320 dictStream <<
"}" << std::endl;
1322 dictStream << std::endl;
1331llvm::StringRef
GrabIndex(
const cling::Interpreter& interp,
const clang::FieldDecl &member,
int printError)
1334 llvm::StringRef where;
1337 if (
index.size() == 0 && printError) {
1338 const char *errorstring;
1341 errorstring =
"is not an integer";
1344 errorstring =
"has not been defined before the array";
1347 errorstring =
"is a private member of a parent class";
1350 errorstring =
"is not known";
1353 errorstring =
"UNKNOWN ERROR!!!!";
1356 if (where.size() == 0) {
1358 member.getParent()->getName().str().c_str(), member.getName().str().c_str());
1361 member.getParent()->getName().str().c_str(), member.getName().str().c_str(), where.str().c_str(), errorstring);
1370 const cling::Interpreter &interp,
1372 std::ostream &dictStream)
1374 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1375 if (clxx ==
nullptr)
return;
1382 int enclSpaceNesting = 0;
1388 dictStream <<
"//_______________________________________"
1389 <<
"_______________________________________" << std::endl;
1390 if (add_template_keyword) dictStream <<
"template <> ";
1391 dictStream <<
"void " << clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1392 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1400 int basestreamer = 0;
1401 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1405 string base_fullname;
1408 if (strstr(base_fullname.c_str(),
"::")) {
1410 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1411 <<
" typedef " << base_fullname <<
" baseClass" << basestreamer <<
";" << std::endl
1412 <<
" baseClass" << basestreamer <<
"::Streamer(R__b);" << std::endl;
1414 dictStream <<
" " << base_fullname <<
"::Streamer(R__b);" << std::endl;
1419 if (!basestreamer) {
1420 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1421 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1423 dictStream <<
"}" << std::endl << std::endl;
1424 while (enclSpaceNesting) {
1425 dictStream <<
"} // namespace " << nsname.c_str() << std::endl;
1432 string classname = fullname;
1433 if (strstr(fullname.c_str(),
"::")) {
1435 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1436 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1437 classname =
"thisClass";
1439 for (
int i = 0; i < 2; i++) {
1444 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1445 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1446 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1448 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1449 dictStream <<
" } else {" << std::endl;
1450 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1455 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1459 string base_fullname;
1462 if (strstr(base_fullname.c_str(),
"::")) {
1464 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1465 <<
" typedef " << base_fullname <<
" baseClass" << base <<
";" << std::endl
1466 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1469 dictStream <<
" " << base_fullname <<
"::Streamer(R__b);" << std::endl;
1475 for (clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
1480 clang::QualType
type = field_iter->getType();
1481 std::string type_name =
type.getAsString(clxx->getASTContext().getPrintingPolicy());
1491 if (strstr(type_name.c_str(),
"Float16_t")) isFloat16 = 1;
1495 if (strstr(type_name.c_str(),
"Double32_t")) isDouble32 = 1;
1498 if (strncmp(comment,
"!", 1)) {
1501 if (underling_type->isFundamentalType() || underling_type->isEnumeralType()) {
1502 if (
type.getTypePtr()->isConstantArrayType() &&
1503 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1504 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1508 dictStream <<
" int R__i;" << std::endl;
1511 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1513 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());
1514 dictStream <<
" ;//R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1516 dictStream <<
" ;//R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1518 }
else if (
type.getTypePtr()->isPointerType()) {
1519 llvm::StringRef indexvar =
GrabIndex(interp, **field_iter, i == 0);
1520 if (indexvar.size() == 0) {
1522 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
1523 dictStream <<
" //R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1525 dictStream <<
" //R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1529 dictStream <<
" delete [] " << field_iter->getName().str() <<
";" << std::endl
1534 <<
"," << indexvar.str() <<
");" << std::endl;
1535 }
else if (isDouble32) {
1537 <<
"," << indexvar.str() <<
");" << std::endl;
1540 <<
"," << indexvar.str() <<
");" << std::endl;
1544 dictStream <<
" R__b.WriteFastArrayFloat16("
1545 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1546 }
else if (isDouble32) {
1547 dictStream <<
" R__b.WriteFastArrayDouble32("
1548 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1550 dictStream <<
" R__b.WriteFastArray("
1551 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1555 }
else if (
type.getTypePtr()->isArrayType()) {
1557 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1558 if (underling_type->isEnumeralType())
1559 dictStream <<
" R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() <<
");" << std::endl;
1563 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1564 }
else if (isDouble32) {
1566 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1569 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1573 if (underling_type->isEnumeralType()) {
1574 dictStream <<
" R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() <<
");" << std::endl;
1577 dictStream <<
" R__b.ReadStaticArrayFloat16(" << field_iter->getName().str() <<
");" << std::endl;
1578 }
else if (isDouble32) {
1579 dictStream <<
" R__b.ReadStaticArrayDouble32(" << field_iter->getName().str() <<
");" << std::endl;
1582 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1587 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1590 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1591 if (underling_type->isEnumeralType())
1592 dictStream <<
" R__b.WriteArray((Int_t*)" << field_iter->getName().str() <<
", "
1593 << s <<
");" << std::endl;
1594 else if (isFloat16) {
1596 <<
"*)" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1597 }
else if (isDouble32) {
1599 <<
"*)" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1602 <<
"*)" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1605 if (underling_type->isEnumeralType())
1606 dictStream <<
" R__b.WriteArray((Int_t*)" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1607 else if (isFloat16) {
1608 dictStream <<
" R__b.WriteArrayFloat16(" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1609 }
else if (isDouble32) {
1610 dictStream <<
" R__b.WriteArrayDouble32(" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1612 dictStream <<
" R__b.WriteArray(" << field_iter->getName().str() <<
", " << s <<
");" << std::endl;
1616 }
else if (underling_type->isEnumeralType()) {
1618 dictStream <<
" void *ptr_" << field_iter->getName().str() <<
" = (void*)&" << field_iter->getName().str() <<
";\n";
1619 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" << field_iter->getName().str() <<
");" << std::endl;
1621 dictStream <<
" R__b << (Int_t)" << field_iter->getName().str() <<
";" << std::endl;
1626 <<
"=Float16_t(R_Dummy);}" << std::endl;
1629 }
else if (isDouble32) {
1632 <<
"=Double32_t(R_Dummy);}" << std::endl;
1654 if (
type.getTypePtr()->isConstantArrayType() &&
1655 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1656 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1660 dictStream <<
" int R__i;" << std::endl;
1663 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1668 dictStream <<
" R__b << (TObject*)" << field_iter->getName().str();
1673 dictStream <<
"[R__i];" << std::endl;
1674 }
else if (
type.getTypePtr()->isPointerType()) {
1682 ROOT::TMetaUtils::Error(
nullptr,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
1683 dictStream <<
" //R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1685 dictStream <<
" //R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);";
1689 dictStream <<
" " << field_iter->getName().str() <<
"->Streamer(R__b);" << std::endl;
1703 dictStream <<
" R__b << (TObject*)" << field_iter->getName().str() <<
";" << std::endl;
1709 }
else if (
const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1713 dictStream <<
" int R__i;" << std::endl;
1716 dictStream <<
" for (R__i = 0; R__i < " << s <<
"; R__i++)" << std::endl;
1717 std::string mTypeNameStr;
1719 const char *mTypeName = mTypeNameStr.c_str();
1720 const char *constwd =
"const ";
1721 if (strncmp(constwd, mTypeName, strlen(constwd)) == 0) {
1722 mTypeName += strlen(constwd);
1723 dictStream <<
" const_cast< " << mTypeName <<
" &>(" << field_iter->getName().str();
1725 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1729 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1735 dictStream <<
" R__b.StreamObject(&(" << field_iter->getName().str() <<
"),typeid("
1736 << field_iter->getName().str() <<
"));" << std::endl;
1747 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1748 <<
" }" << std::endl
1749 <<
"}" << std::endl << std::endl;
1751 while (enclSpaceNesting) {
1752 dictStream <<
"} // namespace " << nsname.c_str() << std::endl;
1760 const cling::Interpreter &interp,
1762 std::ostream &dictStream)
1766 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1767 if (clxx ==
nullptr)
return;
1772 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1784 int enclSpaceNesting = 0;
1790 dictStream <<
"//_______________________________________"
1791 <<
"_______________________________________" << std::endl;
1792 if (add_template_keyword) dictStream <<
"template <> ";
1793 dictStream <<
"void " << clsname <<
"::Streamer(TBuffer &R__b)" << std::endl
1795 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1796 <<
" if (R__b.IsReading()) {" << std::endl
1797 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1798 <<
" } else {" << std::endl
1799 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1800 <<
" }" << std::endl
1801 <<
"}" << std::endl << std::endl;
1803 while (enclSpaceNesting) {
1804 dictStream <<
"} // namespace " << nsname << std::endl;
1812 const cling::Interpreter &interp,
1814 std::ostream &dictStream,
1815 bool isAutoStreamer)
1817 if (isAutoStreamer) {
1827 std::string &code_for_parser)
1829 code_for_parser +=
"#ifdef __CINT__\n\n";
1830 code_for_parser +=
"#pragma link off all globals;\n";
1831 code_for_parser +=
"#pragma link off all classes;\n";
1832 code_for_parser +=
"#pragma link off all functions;\n\n";
1834 for (std::string& arg : InputFiles) {
1836 int nostr = 0, noinp = 0, bcnt = 0,
l = arg.length() - 1;
1837 for (
int j = 0; j < 3; j++) {
1838 if (arg[
l] ==
'-') {
1843 if (arg[
l] ==
'!') {
1848 if (arg[
l] ==
'+') {
1854 if (nostr || noinp) {
1856 if (nostr) strlcat(trail,
"-", 3);
1857 if (noinp) strlcat(trail,
"!", 3);
1860 strlcpy(trail,
"+", 3);
1864 llvm::SmallString<256> filestem = llvm::sys::path::filename(arg);
1865 llvm::sys::path::replace_extension(filestem,
"");
1867 code_for_parser +=
"#pragma link C++ class ";
1868 code_for_parser += filestem.str().str();
1869 if (nostr || noinp || bcnt)
1870 code_for_parser += trail;
1871 code_for_parser +=
";\n";
1874 code_for_parser +=
"\n#endif\n";
1882bool Which(cling::Interpreter &interp,
const char *fname,
string &pname)
1887 static const char *fopenopts =
"rb";
1889 static const char *fopenopts =
"r";
1893 fp = fopen(pname.c_str(), fopenopts);
1899 llvm::SmallVector<std::string, 10> includePaths;
1901 interp.GetIncludePaths(includePaths,
false,
false);
1903 const size_t nPaths = includePaths.size();
1904 for (
size_t i = 0; i < nPaths; i += 1 ) {
1908 fp = fopen(pname.c_str(), fopenopts);
1930 const char *inc = strstr(original,
"\\inc\\");
1932 inc = strstr(original,
"/inc/");
1933 if (inc && strlen(inc) > 5)
1953 cling::Interpreter &interp,
1956 std::ostringstream out;
1961 if (interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1962 const std::string &hdrName
1980static bool WriteAST(llvm::StringRef fileName, clang::CompilerInstance *compilerInstance,
1981 llvm::StringRef iSysRoot,
1982 clang::Module *module =
nullptr)
1985 llvm::SmallVector<char, 128> buffer;
1986 llvm::BitstreamWriter stream(buffer);
1987 clang::ASTWriter
writer(stream, buffer, compilerInstance->getModuleCache(), {});
1988 std::unique_ptr<llvm::raw_ostream> out =
1989 compilerInstance->createOutputFile(fileName,
true,
1998 compilerInstance->getFrontendOpts().RelocatablePCH =
true;
2000 writer.WriteAST(compilerInstance->getSema(), fileName.str(), module, iSysRoot);
2003 out->write(&buffer.front(), buffer.size());
2015 const std::string ¤tDirectory)
2017 assert(modGen.
IsPCH() &&
"modGen must be in PCH mode");
2019 std::string iSysRoot(
"/DUMMY_SYSROOT/include/");
2027static bool IncludeHeaders(
const std::vector<std::string> &headers, cling::Interpreter &interpreter)
2030 if (headers.empty())
2034 std::stringstream includes;
2035 for (
const std::string &header : headers) {
2036 includes <<
"#include \"" << header <<
"\"\n";
2038 std::string includeListStr = includes.str();
2039 auto result = interpreter.declare(includeListStr);
2040 return result == cling::Interpreter::CompilationResult::kSuccess;
2048 char platformDefines[64] = {0};
2049#ifdef __INTEL_COMPILER
2050 snprintf(platformDefines, 64,
"-DG__INTEL_COMPILER=%ld", (
long)__INTEL_COMPILER);
2051 clingArgs.push_back(platformDefines);
2054 snprintf(platformDefines, 64,
"-DG__xlC=%ld", (
long)__xlC__);
2055 clingArgs.push_back(platformDefines);
2058 snprintf(platformDefines, 64,
"-DG__GNUC=%ld", (
long)__GNUC__);
2059 snprintf(platformDefines, 64,
"-DG__GNUC_VER=%ld", (
long)__GNUC__ * 1000 + __GNUC_MINOR__);
2060 clingArgs.push_back(platformDefines);
2062#ifdef __GNUC_MINOR__
2063 snprintf(platformDefines, 64,
"-DG__GNUC_MINOR=%ld", (
long)__GNUC_MINOR__);
2064 clingArgs.push_back(platformDefines);
2067 snprintf(platformDefines, 64,
"-DG__HP_aCC=%ld", (
long)__HP_aCC);
2068 clingArgs.push_back(platformDefines);
2071 snprintf(platformDefines, 64,
"-DG__sun=%ld", (
long)__sun);
2072 clingArgs.push_back(platformDefines);
2075 snprintf(platformDefines, 64,
"-DG__SUNPRO_CC=%ld", (
long)__SUNPRO_CC);
2076 clingArgs.push_back(platformDefines);
2078#ifdef _STLPORT_VERSION
2080 snprintf(platformDefines, 64,
"-DG__STLPORT_VERSION=%ld", (
long)_STLPORT_VERSION);
2081 clingArgs.push_back(platformDefines);
2084 snprintf(platformDefines, 64,
"-DG__ia64=%ld", (
long)__ia64__);
2085 clingArgs.push_back(platformDefines);
2088 snprintf(platformDefines, 64,
"-DG__x86_64=%ld", (
long)__x86_64__);
2089 clingArgs.push_back(platformDefines);
2092 snprintf(platformDefines, 64,
"-DG__i386=%ld", (
long)__i386__);
2093 clingArgs.push_back(platformDefines);
2096 snprintf(platformDefines, 64,
"-DG__arm=%ld", (
long)__arm__);
2097 clingArgs.push_back(platformDefines);
2100 snprintf(platformDefines, 64,
"-DG__WIN32=%ld", (
long)_WIN32);
2101 clingArgs.push_back(platformDefines);
2104 snprintf(platformDefines, 64,
"-DG__WIN32=%ld", (
long)WIN32);
2105 clingArgs.push_back(platformDefines);
2109 snprintf(platformDefines, 64,
"-DG__WIN64=%ld", (
long)_WIN64);
2110 clingArgs.push_back(platformDefines);
2113 snprintf(platformDefines, 64,
"-DG__MSC_VER=%ld", (
long)_MSC_VER);
2114 clingArgs.push_back(platformDefines);
2115 snprintf(platformDefines, 64,
"-DG__VISUAL=%ld", (
long)_MSC_VER);
2116 clingArgs.push_back(platformDefines);
2125 return llvm::sys::path::filename(path).str();
2135 if (std::string::npos != pos) {
2136 dirname.assign(path.begin(), path.begin() + pos + 1);
2147 std::string dictLocation;
2149 return !dictLocation.empty();
2155 std::string &rootmapLibName)
2159 if (rootmapFileName.empty()) {
2161 rootmapFileName = rootmapLibName.substr(0, libExtensionPos) +
".rootmap";
2162 size_t libCleanNamePos = rootmapLibName.find_last_of(
gPathSeparator) + 1;
2163 rootmapLibName = rootmapLibName.substr(libCleanNamePos, std::string::npos);
2165 rootmapLibName.c_str(),
2166 rootmapFileName.c_str());
2175 std::string &ctxtName,
2176 const cling::Interpreter &interpreter,
2177 bool treatParent =
true)
2179 const clang::DeclContext *outerCtxt = treatParent ? theContext.getParent() : &theContext;
2181 if (!outerCtxt)
return;
2183 if (
const clang::RecordDecl *thisRcdDecl = llvm::dyn_cast<clang::RecordDecl>(outerCtxt)) {
2193 std::string &ctxtName,
2194 const cling::Interpreter &interpreter)
2196 const clang::DeclContext *theContext = theDecl.getDeclContext();
2204 const cling::Interpreter &interp)
2206 if (!decls.empty()) {
2207 std::string autoLoadKey;
2208 for (
auto &
d : decls) {
2212 if (autoLoadKey.empty()) {
2213 names.push_back(
d->getQualifiedNameAsString());
2231 const std::string &rootmapLibName,
2232 const std::list<std::string> &classesDefsList,
2233 const std::list<std::string> &classesNames,
2234 const std::list<std::string> &nsNames,
2235 const std::list<std::string> &tdNames,
2236 const std::list<std::string> &enNames,
2237 const std::list<std::string> &varNames,
2239 const std::unordered_set<std::string> headersToIgnore)
2242 std::ofstream rootmapFile(rootmapFileName.c_str());
2250 std::unordered_set<std::string> classesKeys;
2254 if (!classesNames.empty() || !nsNames.empty() || !tdNames.empty() ||
2255 !enNames.empty() || !varNames.empty()) {
2258 if (!classesDefsList.empty()) {
2259 rootmapFile <<
"{ decls }\n";
2260 for (
auto & classDef : classesDefsList) {
2261 rootmapFile << classDef << std::endl;
2263 rootmapFile <<
"\n";
2265 rootmapFile <<
"[ " << rootmapLibName <<
" ]\n";
2268 if (!classesNames.empty()) {
2269 rootmapFile <<
"# List of selected classes\n";
2270 for (
auto & className : classesNames) {
2271 rootmapFile <<
"class " << className << std::endl;
2272 classesKeys.insert(className);
2275 std::unordered_set<std::string> treatedHeaders;
2276 for (
auto & className : classesNames) {
2278 if (className.find(
"<") != std::string::npos)
continue;
2279 if (headersClassesMap.count(className)) {
2280 auto &headers = headersClassesMap.at(className);
2281 if (!headers.empty()){
2282 auto &header = headers.front();
2283 if (treatedHeaders.insert(header).second &&
2284 headersToIgnore.find(header) == headersToIgnore.end() &&
2286 rootmapFile <<
"header " << header << std::endl;
2294 if (!nsNames.empty()) {
2295 rootmapFile <<
"# List of selected namespaces\n";
2296 for (
auto & nsName : nsNames) {
2297 rootmapFile <<
"namespace " << nsName << std::endl;
2302 if (!tdNames.empty()) {
2303 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2304 for (
const auto & autoloadKey : tdNames)
2305 if (classesKeys.insert(autoloadKey).second)
2306 rootmapFile <<
"typedef " << autoloadKey << std::endl;
2311 if (!enNames.empty()){
2312 rootmapFile <<
"# List of selected enums and outer classes\n";
2313 for (
const auto & autoloadKey : enNames)
2314 if (classesKeys.insert(autoloadKey).second)
2315 rootmapFile <<
"enum " << autoloadKey << std::endl;
2319 if (!varNames.empty()){
2320 rootmapFile <<
"# List of selected vars\n";
2321 for (
const auto & autoloadKey : varNames)
2322 if (classesKeys.insert(autoloadKey).second)
2323 rootmapFile <<
"var " << autoloadKey << std::endl;
2337 auto nsPattern =
'{';
auto nsPatternLength = 1;
2338 auto foundNsPos =
line.find_last_of(nsPattern);
2339 if (foundNsPos == std::string::npos)
return {
"",
""};
2340 foundNsPos+=nsPatternLength;
2341 auto extNs =
line.substr(0,foundNsPos);
2343 auto nsEndPattern =
'}';
2344 auto foundEndNsPos =
line.find(nsEndPattern);
2345 auto contained =
line.substr(foundNsPos, foundEndNsPos-foundNsPos);
2347 return {extNs, contained};
2363 std::map<std::string, std::string> nsEntitiesMap;
2364 std::list<std::string> optFwdDeclList;
2365 for (
auto const & fwdDecl : fwdDeclarationsList){
2368 if (extNsAndEntities.first.empty()) {
2370 optFwdDeclList.push_front(fwdDecl);
2372 auto currentVal = nsEntitiesMap[extNsAndEntities.first];
2373 nsEntitiesMap[extNsAndEntities.first] = currentVal +=extNsAndEntities.second;
2377 std::string optFwdDecl;
2378 for (
auto const & extNsAndEntities : nsEntitiesMap) {
2379 optFwdDecl = extNsAndEntities.first;
2380 optFwdDecl += extNsAndEntities.second;
2381 for (
int i = 0; i < std::count(optFwdDecl.begin(), optFwdDecl.end(),
'{'); ++i ){
2384 optFwdDeclList.push_front(optFwdDecl);
2387 return optFwdDeclList;
2395 std::list<std::string> &el_list,
2396 std::unordered_set<std::string> &el_set)
2398 std::stringstream elStream(el);
2401 while (getline(elStream, tmp,
'\n')) {
2403 if (el_set.insert(tmp).second && !tmp.empty()) {
2404 el_list.push_back(tmp);
2415 std::list<std::string> &classesList,
2416 std::list<std::string> &classesListForRootmap,
2417 std::list<std::string> &fwdDeclarationsList,
2418 const cling::Interpreter &interpreter)
2426 std::unordered_set<std::string> classesSet;
2427 std::unordered_set<std::string> outerMostClassesSet;
2429 std::string attrName, attrValue;
2430 bool isClassSelected;
2431 std::unordered_set<std::string> availableFwdDecls;
2432 std::string fwdDeclaration;
2434 fwdDeclaration =
"";
2440 fwdDeclaration =
"";
2447 isClassSelected =
true;
2448 const clang::RecordDecl *rDecl = selClass.GetRecordDecl();
2449 std::string normalizedName;
2450 normalizedName = selClass.GetNormalizedName();
2451 if (!normalizedName.empty() &&
2452 !classesSet.insert(normalizedName).second &&
2453 outerMostClassesSet.count(normalizedName) == 0) {
2454 std::cerr <<
"FATAL: A class with normalized name " << normalizedName
2455 <<
" was already selected. This means that two different instances of"
2456 <<
" clang::RecordDecl had the same name, which is not possible."
2457 <<
" This can be a hint of a serious problem in the class selection."
2458 <<
" In addition, the generated dictionary would not even compile.\n";
2461 classesList.push_back(normalizedName);
2464 const char *reqName(selClass.GetRequestedName());
2467 fwdDeclaration =
"";
2472 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl)) {
2473 fwdDeclaration =
"";
2476 std::string fwdDeclarationTemplateSpec;
2478 fwdDeclaration +=
'\n' + fwdDeclarationTemplateSpec;
2486 for (
auto ait = rDecl->attr_begin(); ait != rDecl->attr_end(); ++ait) {
2488 attrName ==
"rootmap" &&
2489 attrValue ==
"false") {
2490 attrName = attrValue =
"";
2491 isClassSelected =
false;
2495 if (isClassSelected) {
2511 std::string outerMostClassName;
2513 if (!outerMostClassName.empty() &&
2514 !llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl) &&
2515 classesSet.insert(outerMostClassName).second &&
2516 outerMostClassesSet.insert(outerMostClassName).second) {
2517 classesListForRootmap.push_back(outerMostClassName);
2519 classesListForRootmap.push_back(normalizedName);
2520 if (reqName && reqName[0] && reqName != normalizedName) {
2521 classesListForRootmap.push_back(reqName);
2526 std::string demangledName = selClass.GetDemangledTypeInfo();
2527 if (!demangledName.empty()) {
2532 if (demangledName != normalizedName && (!reqName || demangledName != reqName)) {
2534 classesListForRootmap.push_back(demangledName);
2540 classesListForRootmap.sort();
2553 for (RScanner::NamespaceColl_t::const_iterator selNsIter = scan.
fSelectedNamespaces.begin();
2568 if (clang::CXXRecordDecl *CXXRD =
2569 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
2581 if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
2584 const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2587 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2603 if (interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2604 "#include \"TFile.h\"\n"
2605 "#include \"TObjArray.h\"\n"
2606 "#include \"TVirtualArray.h\"\n"
2607 "#include \"TStreamerElement.h\"\n"
2608 "#include \"TProtoClass.h\"\n"
2609 "#include \"TBaseClass.h\"\n"
2610 "#include \"TListOfDataMembers.h\"\n"
2611 "#include \"TListOfEnums.h\"\n"
2612 "#include \"TListOfEnumsWithLock.h\"\n"
2613 "#include \"TDataMember.h\"\n"
2614 "#include \"TEnum.h\"\n"
2615 "#include \"TEnumConstant.h\"\n"
2616 "#include \"TDictAttributeMap.h\"\n"
2617 "#include \"TMessageHandler.h\"\n"
2618 "#include \"TArray.h\"\n"
2619 "#include \"TRefArray.h\"\n"
2620 "#include \"root_std_complex.h\"\n")
2621 != cling::Interpreter::kSuccess)
2632 cling::Interpreter &interp,
2637 bool writeEmptyRootPCM)
2641 bool needsCollectionProxy =
false;
2663 auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
2664 if (nsName.find(
"(anonymous)") == std::string::npos)
2669 if (!selClass.GetRecordDecl()->isCompleteDefinition()) {
2673 if (selClass.RequestOnlyTClass()) {
2681 if (clang::CXXRecordDecl *CXXRD =
2682 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
2686 const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2694 }
else if (CRD->getName() ==
"RVec") {
2695 static const clang::DeclContext *vecOpsDC =
nullptr;
2697 vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
2698 interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
2699 if (vecOpsDC && vecOpsDC->Equals(CRD->getDeclContext())) {
2707 needsCollectionProxy);
2722 if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
2726 const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2738 if (!selClass.GetRecordDecl()->isCompleteDefinition() || !selClass.RequestOnlyTClass()) {
2742 const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2747 needsCollectionProxy);
2776 if (finRetCode != 0)
return finRetCode;
2786 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2787 <<
"#define R__DICTIONARY_FILENAME " << main_dictname << std::endl
2790 <<
"#define R__NO_DEPRECATION" << std::endl
2795 <<
"\n/*******************************************************************/\n"
2796 <<
"#include <stddef.h>\n"
2797 <<
"#include <stdio.h>\n"
2798 <<
"#include <stdlib.h>\n"
2799 <<
"#include <string.h>\n"
2800 <<
"#include <assert.h>\n"
2801 <<
"#define G__DICTIONARY\n"
2802 <<
"#include \"ROOT/RConfig.hxx\"\n"
2803 <<
"#include \"TClass.h\"\n"
2804 <<
"#include \"TDictAttributeMap.h\"\n"
2805 <<
"#include \"TInterpreter.h\"\n"
2806 <<
"#include \"TROOT.h\"\n"
2807 <<
"#include \"TBuffer.h\"\n"
2808 <<
"#include \"TMemberInspector.h\"\n"
2809 <<
"#include \"TInterpreter.h\"\n"
2810 <<
"#include \"TVirtualMutex.h\"\n"
2811 <<
"#include \"TError.h\"\n\n"
2812 <<
"#ifndef G__ROOT\n"
2813 <<
"#define G__ROOT\n"
2815 <<
"#include \"RtypesImp.h\"\n"
2816 <<
"#include \"TIsAProxy.h\"\n"
2817 <<
"#include \"TFileMergeInfo.h\"\n"
2818 <<
"#include <algorithm>\n"
2819 <<
"#include \"TCollectionProxyInfo.h\"\n"
2820 <<
"/*******************************************************************/\n\n"
2821 <<
"#include \"TDataMember.h\"\n\n";
2828 dictStream <<
"// The generated code does not explicitly qualify STL entities\n"
2829 <<
"namespace std {} using namespace std;\n\n";
2835 const std::string &includeForSource,
2836 const std::string &extraIncludes)
2838 dictStream <<
"// Header files passed as explicit arguments\n"
2839 << includeForSource << std::endl
2840 <<
"// Header files passed via #pragma extra_include\n"
2841 << extraIncludes << std::endl;
2847#if defined(R__IOSSIM) || defined(R__IOS)
2872 return filename +
"_tmp_" + std::to_string(getpid());
2879 if (nameStr.empty())
return;
2881 std::string tmpNameStr(getTmpFileName(nameStr));
2884 const char *
name(nameStr.c_str());
2885 const char *tmpName(tmpNameStr.c_str());
2887 m_names.push_back(nameStr);
2888 m_tempNames.push_back(tmpNameStr);
2892 if (0 == std::rename(
name , tmpName)) {
2897 nameStr = tmpNameStr;
2908 for (
unsigned int i = 0; i < m_size; ++i) {
2909 const char *tmpName = m_tempNames[i].c_str();
2911 std::ifstream ifile(tmpName);
2916 if (ifile.is_open())
2918 if (0 != std::remove(tmpName)) {
2931 for (
unsigned int i = 0; i < m_size; ++i) {
2932 const char *tmpName = m_tempNames[i].c_str();
2933 const char *
name = m_names[i].c_str();
2935 std::ifstream ifile(tmpName);
2940 if (ifile.is_open())
2946 if (0 != std::rename(tmpName ,
name)) {
2947 if (llvm::sys::fs::copy_file(tmpName ,
name)) {
2948 llvm::sys::fs::remove(tmpName);
2952 if (0 != std::rename(tmpName ,
name)) {
2964 size_t i = std::distance(m_tempNames.begin(),
2965 find(m_tempNames.begin(), m_tempNames.end(), tmpFileName));
2966 if (i == m_tempNames.size())
return m_emptyString;
2973 std::cout <<
"Restoring files in temporary file catalog:\n";
2974 for (
unsigned int i = 0; i < m_size; ++i) {
2975 std::cout << m_tempNames[i] <<
" --> " << m_names[i] << std::endl;
2992 std::string splitDictName(tmpCatalog.
getFileName(dictpathname));
2993 const size_t dotPos = splitDictName.find_last_of(
".");
2994 splitDictName.insert(dotPos,
"_classdef");
2996 return new std::ofstream(splitDictName.c_str());
3005 std::list<std::string> &diagnosticPragmas)
3007 static const std::string pattern(
"-Wno-");
3009 if (arg.find(pattern) != 0)
3011 if (arg ==
"-Wno-noexcept-type") {
3018 diagnosticPragmas.push_back(arg);
3024 cling::Interpreter &interp)
3027 std::string fwdDecl;
3028 std::string initStr(
"{");
3030 for (
auto & strigNargsToKeepPair : fwdDeclnArgsToSkipColl) {
3031 auto &clTemplDecl = *strigNargsToKeepPair.first;
3032 FwdDeclFromTmplDecl(clTemplDecl , interp, fwdDecl);
3035 + std::to_string(strigNargsToKeepPair.second)
3038 if (!fwdDeclnArgsToSkipColl.empty())
3049 if (qt.isNull())
return qt;
3050 clang::QualType thisQt(qt);
3051 while (thisQt->isPointerType() ||
3052 thisQt->isReferenceType()) {
3053 thisQt = thisQt->getPointeeType();
3063 const cling::Interpreter &interp,
3064 std::set<const clang::CXXRecordDecl *> &visitedDecls)
3066 std::list<std::string> headers;
3069 cling::Interpreter::PushTransactionRAII RAII(&interp);
3072 if (!visitedDecls.insert(rcd.getCanonicalDecl()).second)
3076 if (
const clang::ClassTemplateSpecializationDecl *tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd)) {
3079 for (
auto & tArg : tsd->getTemplateArgs().asArray()) {
3080 if (clang::TemplateArgument::ArgKind::Type != tArg.getKind())
continue;
3082 if (tArgQualType.isNull())
continue;
3083 if (
const clang::CXXRecordDecl *tArgCxxRcd = tArgQualType->getAsCXXRecordDecl()) {
3084 headers.splice(headers.end(),
RecordDecl2Headers(*tArgCxxRcd, interp, visitedDecls));
3091 for (
auto baseIt = tsd->bases_begin(); baseIt != tsd->bases_end(); baseIt++) {
3093 if (baseQualType.isNull())
continue;
3094 if (
const clang::CXXRecordDecl *baseRcdPtr = baseQualType->getAsCXXRecordDecl()) {
3095 headers.splice(headers.end(),
RecordDecl2Headers(*baseRcdPtr, interp, visitedDecls));
3100 for (
auto declIt = tsd->decls_begin(); declIt != tsd->decls_end(); ++declIt) {
3101 if (
const clang::FieldDecl *fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*declIt)) {
3103 if (fieldQualType.isNull()) continue ;
3104 if (
const clang::CXXRecordDecl *fieldCxxRcd = fieldQualType->getAsCXXRecordDecl()) {
3105 if (fieldCxxRcd->hasDefinition())
3106 headers.splice(headers.end(),
RecordDecl2Headers(*fieldCxxRcd, interp, visitedDecls));
3112 for (
auto methodIt = tsd->method_begin(); methodIt != tsd->method_end(); ++methodIt) {
3114 for (
auto & fPar : methodIt->parameters()) {
3116 if (fParQualType.isNull())
continue;
3117 if (
const clang::CXXRecordDecl *fParCxxRcd = fParQualType->getAsCXXRecordDecl()) {
3118 if (fParCxxRcd->hasDefinition())
3119 headers.splice(headers.end(),
RecordDecl2Headers(*fParCxxRcd, interp, visitedDecls));
3124 if (retQualType.isNull())
continue;
3125 if (
const clang::CXXRecordDecl *retCxxRcd = retQualType->getAsCXXRecordDecl()) {
3126 if (retCxxRcd->hasDefinition())
3135 headers.emplace_back(header);
3148 if (
auto dclCtxt= rcd.getDeclContext()){
3149 if (! dclCtxt->isStdNamespace()){
3158 auto clAsTmplSpecDecl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd);
3159 if (!clAsTmplSpecDecl)
return false;
3164 auto& astCtxt = rcd.getASTContext();
3165 auto& templInstArgs = clAsTmplSpecDecl->getTemplateInstantiationArgs();
3166 for (
auto&& arg : templInstArgs.asArray()){
3168 auto argKind = arg.getKind();
3169 if (argKind != clang::TemplateArgument::Type){
3170 if (argKind == clang::TemplateArgument::Integral)
continue;
3174 auto argQualType = arg.getAsType();
3175 auto isPOD = argQualType.isPODType(astCtxt);
3177 if (isPOD)
continue;
3179 auto argType = argQualType.getTypePtr();
3180 if (
auto recType = llvm::dyn_cast<clang::RecordType>(argType)){
3183 if (isArgGoodForAutoParseMap)
continue;
3202 const cling::Interpreter &interp)
3204 std::set<const clang::CXXRecordDecl *> visitedDecls;
3205 std::unordered_set<std::string> buffer;
3206 std::string autoParseKey;
3209 for (
auto & annotatedRcd : annotatedRcds) {
3210 if (
const clang::CXXRecordDecl *cxxRcd =
3211 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(annotatedRcd.GetRecordDecl())) {
3213 visitedDecls.clear();
3217 headers.remove_if([&buffer](
const std::string & s) {
3218 return !buffer.insert(s).second;
3221 if (autoParseKey.empty()) autoParseKey = annotatedRcd.GetNormalizedName();
3223 headersDeclsMap[autoParseKey] = headers;
3224 headersDeclsMap[annotatedRcd.GetRequestedName()] = headers;
3226 ROOT::TMetaUtils::Info(
nullptr,
"Class %s is not included in the set of autoparse keys.\n", autoParseKey.c_str());
3231 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(cxxRcd)){
3232 headersClassesMap[autoParseKey] = headersDeclsMap[autoParseKey];
3233 headersClassesMap[annotatedRcd.GetRequestedName()] = headersDeclsMap[annotatedRcd.GetRequestedName()];
3239 for (
auto & tDef : tDefDecls) {
3240 if (clang::CXXRecordDecl *cxxRcd = tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3242 visitedDecls.clear();
3247 headers.remove_if([&buffer](
const std::string & s) {
3248 return !buffer.insert(s).second;
3251 if (autoParseKey.empty()) autoParseKey = tDef->getQualifiedNameAsString();
3252 headersDeclsMap[autoParseKey] = headers;
3257 for (
auto & func : funcDecls) {
3263 for (
auto & var : varDecls) {
3269 for (
auto & en : enumDecls) {
3279 const cling::Interpreter &interp)
3281 std::string newFwdDeclString;
3285 std::string fwdDeclString;
3287 std::unordered_set<std::string> fwdDecls;
3308 std::vector<const clang::Decl *> selectedDecls(scan.
fSelectedClasses.size());
3313 selectedDecls.begin(),
3317 selectedDecls.push_back(TD);
3322 std::string fwdDeclLogs;
3330 std::cout <<
"Logs from forward decl printer: \n"
3347 if (fwdDeclString.empty()) fwdDeclString =
"";
3348 return fwdDeclString;
3355 const std::string &detectedUmbrella,
3356 bool payLoadOnly =
false)
3358 std::string headerName;
3361 std::cout <<
"Class-headers Mapping:\n";
3362 std::string headersClassesMapString =
"";
3363 for (
auto const & classHeaders : headersClassesMap) {
3365 std::cout <<
" o " << classHeaders.first <<
" --> ";
3366 headersClassesMapString +=
"\"";
3367 headersClassesMapString += classHeaders.first +
"\"";
3368 for (
auto const & header : classHeaders.second) {
3369 headerName = (detectedUmbrella == header || payLoadOnly) ?
"payloadCode" :
"\"" + header +
"\"";
3370 headersClassesMapString +=
", " + headerName;
3372 std::cout <<
", " << headerName;
3377 std::cout << std::endl;
3378 headersClassesMapString +=
", \"@\",\n";
3380 headersClassesMapString +=
"nullptr";
3381 return headersClassesMapString;
3404 static const std::vector<std::string> namePrfxes {
3407 auto pos = find_if(namePrfxes.begin(),
3409 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3410 return namePrfxes.end() == pos;
3417 static const std::vector<std::string> uclNamePrfxes {
3421 static const std::set<std::string> unsupportedClassesNormNames{
3424 if ( unsupportedClassesNormNames.count(
name) == 1)
return false;
3425 auto pos = find_if(uclNamePrfxes.begin(),
3426 uclNamePrfxes.end(),
3427 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3428 return uclNamePrfxes.end() == pos;
3438 for (
auto&& aRcd : annotatedRcds){
3439 auto clName = aRcd.GetNormalizedName();
3441 std::cerr <<
"Error: Class " << clName <<
" has been selected but "
3442 <<
"currently the support for its I/O is not yet available. Note that "
3443 << clName <<
", even if not selected, will be available for "
3444 <<
"interpreted code.\n";
3448 std::cerr <<
"Error: It is not necessary to explicitly select class "
3449 << clName <<
". I/O is supported for it transparently.\n";
3461 bool isLocked =
false;
3464 InterpreterCallbacks(interp),
3465 fFilesIncludedByLinkdef(filesIncludedByLinkdef){};
3470 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3471 const clang::FileEntry * , llvm::StringRef ,
3472 llvm::StringRef ,
const clang::Module * ,
3473 clang::SrcMgr::CharacteristicKind )
override
3475 if (isLocked)
return;
3476 if (IsAngled)
return;
3477 auto& PP = m_Interpreter->getCI()->getPreprocessor();
3478 auto curLexer = PP.getCurrentFileLexer();
3479 if (!curLexer)
return;
3480 auto fileEntry = curLexer->getFileEntry();
3481 if (!fileEntry)
return;
3482 auto thisFileName = fileEntry->getName();
3483 auto fileNameAsString = FileName.str();
3485 if (isThisLinkdef) {
3487 if (isTheIncludedLinkdef) {
3488 fFilesIncludedByLinkdef.clear();
3491 fFilesIncludedByLinkdef.emplace_back(fileNameAsString.c_str());
3505 clang::SourceLocation ImportLoc,
3506 bool ForPragma)
override {
3508 using namespace clang;
3509 if (llvm::StringRef(M->Name).endswith(
"ACLiC_dict")) {
3510 Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
3511 HeaderSearch& HS = PP.getHeaderSearchInfo();
3513 Module* CoreModule = HS.lookupModule(
"Core",
false);
3514 assert(M &&
"Must have module Core");
3515 PP.makeModuleVisible(CoreModule, ImportLoc);
3520static llvm::cl::list<std::string>
3523 llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
3526static llvm::cl::opt<std::string>
3528 llvm::cl::desc(
"<output dictionary file>"),
3548 : fChild(Child), fOwnsChild(OwnsChild), fMap(Map)
3560 using namespace clang::diag;
3566 std::string moduleName;
3567 const clang::Module *module =
nullptr;
3570 const auto &ID =
Info.getID();
3571 if (ID == remark_module_build || ID == remark_module_build_done) {
3572 moduleName =
Info.getArgStdStr(0);
3573 module = fMap.findModule(moduleName);
3579 "Couldn't find module %s in the available modulemaps. This"
3580 "prevents us from correctly diagnosing wrongly built modules.\n",
3581 moduleName.c_str());
3594 bool isByproductModule
3596 if (!isByproductModule)
3597 fChild->HandleDiagnostic(DiagLevel,
Info);
3599 if (ID == remark_module_build && !isByproductModule) {
3601 "Building module '%s' implicitly. If '%s' requires a \n"
3602 "dictionary please specify build dependency: '%s' depends on '%s'.\n"
3603 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
3605 moduleName.c_str(), moduleName.c_str());
3613 DiagnosticConsumer::clear();
3616 virtual void BeginSourceFile(
const clang::LangOptions &LangOpts,
const clang::Preprocessor *PP)
override
3618 fChild->BeginSourceFile(LangOpts, PP);
3619 DiagnosticConsumer::BeginSourceFile(LangOpts, PP);
3624 fChild->EndSourceFile();
3625 DiagnosticConsumer::EndSourceFile();
3631 DiagnosticConsumer::finish();
3638#if defined(_WIN32) && defined(_MSC_VER)
3642 const char *EnablePopups = getenv(
"Cling_GuiOnAssert");
3643 if (EnablePopups ==
nullptr || EnablePopups[0] ==
'0') {
3644 ::_set_error_mode(_OUT_TO_STDERR);
3645 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3646 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3647 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3648 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
3649 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3650 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3655static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3657static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3668static llvm::cl::opt<VerboseLevel>
3670 llvm::cl::values(clEnumVal(
v,
"Show errors."),
3671 clEnumVal(
v0,
"Show only fatal errors."),
3672 clEnumVal(
v1,
"Show errors (the same as -v)."),
3673 clEnumVal(
v2,
"Show warnings (default)."),
3674 clEnumVal(
v3,
"Show notes."),
3675 clEnumVal(
v4,
"Show information.")),
3679static llvm::cl::opt<bool>
3680gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3683static llvm::cl::opt<bool>
3684gOptReflex(
"reflex", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3687static llvm::cl::opt<bool>
3688gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3691static llvm::cl::opt<std::string>
3693 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3696static llvm::cl::opt<bool>
3698 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3701static llvm::cl::opt<bool>
3702gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3704static llvm::cl::opt<bool>
3705gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3707static llvm::cl::list<std::string>
3709 llvm::cl::desc(
"Generate rootmap file."),
3711static llvm::cl::opt<std::string>
3713 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3715static llvm::cl::opt<bool>
3717 llvm::cl::desc(
"Generate a C++ module."),
3719static llvm::cl::list<std::string>
3721 llvm::cl::desc(
"Specify a C++ modulemap file."),
3724static llvm::cl::opt<bool>
3726 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3728static llvm::cl::opt<bool>
3730 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3732static llvm::cl::opt<bool>
3734 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3736static llvm::cl::opt<bool>
3738 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3740static llvm::cl::opt<bool>
3742 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3743information and another the interactivity support."),
3745static llvm::cl::opt<bool>
3748 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3750static llvm::cl::opt<std::string>
3752 llvm::cl::desc(
"The path to the library of the built dictionary."),
3754static llvm::cl::list<std::string>
3756 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3758static llvm::cl::list<std::string>
3760 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3764static llvm::cl::opt<bool>
3766 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3774static llvm::cl::opt<bool>
3777 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3779static llvm::cl::opt<bool>
3781 llvm::cl::desc(
"Check the selection syntax only."),
3783static llvm::cl::opt<bool>
3785 llvm::cl::desc(
"Fail if there are warnings."),
3787static llvm::cl::opt<bool>
3789 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3791static llvm::cl::opt<std::string>
3793 llvm::cl::desc(
"Specify an isysroot."),
3795 llvm::cl::init(
"-"));
3796static llvm::cl::list<std::string>
3798 llvm::cl::desc(
"Specify an include path."),
3800static llvm::cl::list<std::string>
3802 llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
3804static llvm::cl::list<std::string>
3806 llvm::cl::desc(
"Specify a system include path."),
3808static llvm::cl::list<std::string>
3810 llvm::cl::desc(
"Specify defined macros."),
3812static llvm::cl::list<std::string>
3814 llvm::cl::desc(
"Specify undefined macros."),
3816static llvm::cl::list<std::string>
3818 llvm::cl::desc(
"Specify compiler diagnostics options."),
3821static llvm::cl::list<std::string>
3823 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file>"),
3825static llvm::cl::list<std::string>
3827 llvm::cl::desc(
"Consumes all unrecognized options."),
3830static llvm::cl::SubCommand
3833static llvm::cl::list<std::string>
3835 llvm::cl::desc(
"Consumes options and sends them to cling."),
3845 clang::Module *module, std::vector<std::array<std::string, 2>> &missingHeaders)
3848 std::vector<clang::Module::Header> moduleHeaders;
3850 [&moduleHeaders](
const clang::Module::Header &
h) { moduleHeaders.push_back(
h); });
3852 bool foundAllHeaders =
true;
3854 auto isHeaderInModule = [&moduleHeaders](
const std::string &header) {
3855 for (
const clang::Module::Header &moduleHeader : moduleHeaders)
3856 if (header == moduleHeader.NameAsWritten)
3864 for (
const std::string &header : modGen.
GetHeaders()) {
3865 if (isHeaderInModule(header))
3868 clang::ModuleMap::KnownHeader SuggestedModule;
3869 const clang::DirectoryLookup *CurDir =
nullptr;
3870 if (
auto FE = headerSearch.LookupFile(
3871 header, clang::SourceLocation(),
3874 clang::ArrayRef<std::pair<const clang::FileEntry *, const clang::DirectoryEntry *>>(),
3877 0, &SuggestedModule,
3884 if (
auto OtherModule = SuggestedModule.getModule()) {
3885 std::string OtherModuleName;
3886 auto TLM = OtherModule->getTopLevelModuleName();
3888 OtherModuleName = TLM.str();
3890 OtherModuleName = OtherModule->Name;
3897 missingHeaders.push_back({header, OtherModuleName});
3900 missingHeaders.push_back({header, {}});
3902 foundAllHeaders =
false;
3904 return foundAllHeaders;
3910 llvm::StringRef LinkdefPath,
const std::string &moduleName)
3912 clang::CompilerInstance *CI = interpreter.getCI();
3913 clang::HeaderSearch &headerSearch = CI->getPreprocessor().getHeaderSearchInfo();
3914 headerSearch.loadTopLevelSystemModules();
3917 clang::Module *module = headerSearch.lookupModule(llvm::StringRef(moduleName));
3922 moduleName.c_str());
3929 std::vector<std::array<std::string, 2>> missingHdrMod;
3932 std::stringstream msgStream;
3933 msgStream <<
"after creating module \"" << module->Name <<
"\" ";
3934 if (!module->PresumedModuleMapFile.empty())
3935 msgStream <<
"using modulemap \"" << module->PresumedModuleMapFile <<
"\" ";
3936 msgStream <<
"the following headers are not part of that module:\n";
3937 for (
auto &
H : missingHdrMod) {
3938 msgStream <<
" " <<
H[0];
3940 msgStream <<
" (already part of module \"" <<
H[1] <<
"\")";
3943 std::string warningMessage = msgStream.str();
3945 bool maybeUmbrella = modGen.
GetHeaders().size() == 1;
3956 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3957 warningMessage.c_str(),
3964 std::vector<std::string> missingHeaders;
3965 std::transform(missingHdrMod.begin(), missingHdrMod.end(), missingHeaders.begin(),
3966 [](
const std::array<std::string, 2>& HdrMod) { return HdrMod[0];});
3969 module->Name.c_str());
3979 llvm::StringRef moduleName = llvm::sys::path::filename(rdictName);
3980 moduleName.consume_front(
"lib");
3981 moduleName.consume_back(
".pcm");
3982 moduleName.consume_back(
"_rdict");
3990 bool isGenreflex =
false)
4001 const char *executableFileName = argv[0];
4003 llvm::sys::PrintStackTraceOnErrorSignal(executableFileName);
4004 llvm::PrettyStackTraceProgram X(argc, argv);
4007#if defined(R__WIN32) && !defined(R__WINGCC)
4012 for (
int iic = 1 ; iic < argc; ++iic) {
4013 std::string iiarg(argv[iic]);
4015 size_t len = iiarg.length();
4017 char *argviic =
new char[
len + 1];
4018 strlcpy(argviic, iiarg.c_str(),
len + 1);
4019 argv[iic] = argviic;
4028 auto &opts = llvm::cl::getRegisteredOptions();
4029 llvm::cl::Option* optHelp = opts[
"help"];
4030 llvm::cl::alias optHelpAlias1(
"h",
4031 llvm::cl::desc(
"Alias for -help"),
4032 llvm::cl::aliasopt(*optHelp));
4033 llvm::cl::alias optHelpAlias2(
"?",
4034 llvm::cl::desc(
"Alias for -help"),
4035 llvm::cl::aliasopt(*optHelp));
4037 llvm::cl::ParseCommandLineOptions(argc, argv,
"rootcling");
4041 std::vector<const char *> clingArgsC;
4042 clingArgsC.push_back(executableFileName);
4044 clingArgsC.push_back(
"-I");
4051 clingArgsC.push_back(Opt.c_str());
4053 auto interp = std::make_unique<cling::Interpreter>(clingArgsC.size(),
4055 llvmResourceDir.c_str());
4058 return interp->getDiagnostics().hasFatalErrorOccurred();
4061 std::string dictname;
4075 llvm::cl::PrintHelpMessage();
4090 if ((fp = fopen(filein.c_str(),
"r")) ==
nullptr) {
4091 ROOT::TMetaUtils::Error(
nullptr,
"%s: The input list file %s does not exist\n", executableFileName, filein.c_str());
4118 ROOT::TMetaUtils::Error(
nullptr,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4119 llvm::cl::PrintHelpMessage();
4123 std::vector<std::string> clingArgs;
4124 clingArgs.push_back(executableFileName);
4125 clingArgs.push_back(
"-iquote.");
4131 std::list<std::string> diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4137 if (GetErrorIgnoreLevel() >
kWarning)
4139 GetWarningsAreErrors() =
true;
4153 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4158 clingArgs.push_back(std::string(
"-D") + PPDefine);
4161 clingArgs.push_back(std::string(
"-U") + PPUndefine);
4164 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(IncludePath));
4171 clingArgs.push_back(
"-isystem");
4172 clingArgs.push_back(llvm::sys::path::convert_to_slash(IncludePath));
4176 for (
const std::string &WDiag :
gOptWDiags) {
4177 const std::string FullWDiag = std::string(
"-W") + WDiag;
4181 clingArgs.push_back(FullWDiag);
4185 clingArgs.push_back(std::string(
"-I") + includeDir);
4187 std::vector<std::string> pcmArgs;
4188 for (
size_t parg = 0,
n = clingArgs.size(); parg <
n; ++parg) {
4189 auto thisArg = clingArgs[parg];
4191 if (thisArg ==
"-c" ||
4197 while (
c ==
' ')
c = thisArg[++
offset];
4201 [&](
const std::string& path){
4202 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4203 if (excludePathsEnd != excludePathPos)
continue;
4205 pcmArgs.push_back(thisArg);
4212 clingArgs.push_back(
"-D__ROOTCLING__");
4215 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4216#elif defined(R__WIN32)
4217 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4220 clingArgs.push_back(
"-D_XKEYCHECK_H");
4222 clingArgs.push_back(
"-DNOMINMAX");
4224 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4227 clingArgs.push_back(
"-fsyntax-only");
4229 clingArgs.push_back(
"-fPIC");
4231 clingArgs.push_back(
"-Xclang");
4232 clingArgs.push_back(
"-fmodules-embed-all-files");
4233 clingArgs.push_back(
"-Xclang");
4234 clingArgs.push_back(
"-main-file-name");
4235 clingArgs.push_back(
"-Xclang");
4236 clingArgs.push_back((dictname +
".h").c_str());
4244 std::string outputFile;
4246 llvm::StringRef moduleName;
4251 auto clingArgsInterpreter = clingArgs;
4260 clingArgsInterpreter.push_back(
"-fmodules");
4261 clingArgsInterpreter.push_back(
"-fno-implicit-module-maps");
4264 clingArgsInterpreter.push_back(
"-fmodule-map-file=" + modulemap);
4266 clingArgsInterpreter.push_back(
"-fmodule-map-file=" +
4271 if (llvm::sys::fs::exists(ModuleMapCWD))
4272 clingArgsInterpreter.push_back(
"-fmodule-map-file=" + ModuleMapCWD);
4279 clingArgsInterpreter.push_back(
"-fmodule-name=" + moduleName.str());
4289 if (moduleName ==
"Core") {
4291 remove((moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4292 remove((moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4293 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4294 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4296 remove((moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4297 remove((moduleCachePath + llvm::sys::path::get_separator() +
"services.pcm").str().c_str());
4301 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4303 remove((moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4305 remove((moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4306 remove((moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4307 remove((moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4308 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4309 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4310 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4311 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4312 }
else if (moduleName ==
"MathCore") {
4313 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Vc.pcm").str().c_str());
4318 clingArgsInterpreter.push_back(
"-fmodules-cache-path=" + moduleCachePath);
4322 clingArgsInterpreter.push_back(
"-v");
4325 std::vector<const char *> clingArgsC;
4326 for (
auto const &clingArg : clingArgsInterpreter) {
4328 std::cerr <<
"Argument \""<< clingArg <<
"\" is not a supported cling argument. "
4329 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4332 clingArgsC.push_back(clingArg.c_str());
4336 std::unique_ptr<cling::Interpreter> owningInterpPtr;
4337 cling::Interpreter* interpPtr =
nullptr;
4339 std::list<std::string> filesIncludedByLinkdef;
4343 clingArgsC.push_back(
"-ffast-math");
4346 owningInterpPtr.reset(
new cling::Interpreter(clingArgsC.size(), &clingArgsC[0],
4347 llvmResourceDir.c_str()));
4348 interpPtr = owningInterpPtr.get();
4351 clingArgsC.push_back(
"-resource-dir");
4352 clingArgsC.push_back(llvmResourceDir.c_str());
4353 clingArgsC.push_back(
nullptr);
4355 extraArgs = &clingArgsC[1];
4358 std::unique_ptr<TRootClingCallbacks> callBacks (
new TRootClingCallbacks(interpPtr, filesIncludedByLinkdef));
4359 interpPtr->setCallbacks(std::move(callBacks));
4362 cling::Interpreter &interp = *interpPtr;
4363 clang::CompilerInstance *CI = interp.getCI();
4365 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4366 CI->getSourceManager().setAllFilesAreTransient(
true);
4368 clang::Preprocessor &PP = CI->getPreprocessor();
4369 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
4370 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
4371 auto &diags = interp.getDiagnostics();
4378 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4383 diags.setClient(recordingClient,
true);
4389 interp.DumpIncludePath();
4394 interp.printIncludedFiles(llvm::outs());
4395 llvm::outs() <<
"\n\n";
4396 llvm::outs().flush();
4399 const clang::LangOptions& LangOpts
4400 = interp.getCI()->getASTContext().getLangOpts();
4401#define LANGOPT(Name, Bits, Default, Description) \
4402 ROOT::TMetaUtils::Info(0, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4403#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4404#include "clang/Basic/LangOptions.def"
4408 interp.getOptions().ErrorOut =
true;
4409 interp.enableRawInput(
true);
4413 if (DepMod.endswith(
"_rdict.pcm")) {
4420 cling::Interpreter::PushTransactionRAII RAII(&interp);
4421 if (!interp.loadModule(DepMod.str(),
false)) {
4430 if (interp.declare(
"#include <assert.h>\n"
4431 "#include \"Rtypes.h\"\n"
4432 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4440 if (interp.declare(
"#include <string>\n"
4441 "#include <RtypesCore.h>\n"
4442 "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4453 clingArgs.push_back(
"-D__CINT__");
4454 clingArgs.push_back(
"-D__MAKECINT__");
4460 std::string interpPragmaSource;
4461 std::string includeForSource;
4462 std::string interpreterDeclarations;
4463 std::string linkdef;
4469 if (isSelectionFile) {
4471 linkdef = optHeaderFileName;
4474 executableFileName, optHeaderFileName.c_str());
4480 std::string fullheader(optHeaderFileName);
4483 if (fullheader[fullheader.length() - 1] ==
'+') {
4484 fullheader.erase(fullheader.length() - 1);
4489 interpPragmaSource += std::string(
"#include \"") + header +
"\"\n";
4490 if (!isSelectionFile) {
4498 includeForSource += std::string(
"#include \"") + fullheader +
"\"\n";
4499 pcmArgs.push_back(header);
4501 interpreterDeclarations += std::string(
"#include \"") + header +
"\"\n";
4506 bool hasSelectionFile = !linkdef.empty();
4507 unsigned expectedHeaderFilesSize = 1 + hasSelectionFile;
4518 if (!newName.empty())
4531 string incCurDir =
"-I";
4532 incCurDir += currentDirectory;
4533 pcmArgs.push_back(incCurDir);
4538 std::stringstream res;
4539 const char* delim=
"\n";
4540 std::copy(diagnosticPragmas.begin(),
4541 diagnosticPragmas.end(),
4542 std::ostream_iterator<std::string>(res, delim));
4543 if (interp.declare(res.str()) != cling::Interpreter::kSuccess) {
4549 class IgnoringPragmaHandler:
public clang::PragmaNamespace {
4551 IgnoringPragmaHandler(
const char* pragma):
4552 clang::PragmaNamespace(pragma) {}
4553 void HandlePragma(clang::Preprocessor &PP,
4554 clang::PragmaIntroducer Introducer,
4555 clang::Token &tok)
override {
4556 PP.DiscardUntilEndOfDirective();
4562 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"link"));
4563 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"extra_include"));
4564 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"read"));
4565 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"create"));
4567 if (!interpreterDeclarations.empty() &&
4568 interp.declare(interpreterDeclarations) != cling::Interpreter::kSuccess) {
4580 pcmArgs.push_back(linkdef);
4588 interp.AddIncludePath(inclPath);
4590 std::stringstream definesUndefinesStr;
4593 if (!definesUndefinesStr.str().empty()) {
4594 if (interp.declare(definesUndefinesStr.str()) != cling::Interpreter::kSuccess) {
4595 ROOT::TMetaUtils::Error(
nullptr,
"Failed to parse -D, -U flags as preprocessor directives:\n%s", definesUndefinesStr.str().c_str());
4606 if (linkdef.empty()) {
4612 std::ofstream fileout;
4614 std::ostream *splitDictStream =
nullptr;
4615 std::unique_ptr<std::ostream> splitDeleter(
nullptr);
4637 splitDeleter.reset(splitDictStream);
4639 splitDictStream = &dictStream;
4642 size_t dh = main_dictname.rfind(
'.');
4643 if (dh != std::string::npos) {
4644 main_dictname.erase(dh);
4647 std::string main_dictname_copy(main_dictname);
4669 string linkdefFilename;
4670 if (linkdef.empty()) {
4671 linkdefFilename =
"in memory";
4673 bool found =
Which(interp, linkdef.c_str(), linkdefFilename);
4681 std::vector<std::pair<std::string, std::string>> namesForExclusion;
4687 SelectionRules selectionRules(interp, normCtxt, namesForExclusion);
4689 std::string extraIncludes;
4694 const unsigned int selRulesInitialSize = selectionRules.
Size();
4698 bool dictSelRulesPresent = selectionRules.
Size() > selRulesInitialSize;
4702 int rootclingRetCode(0);
4704 if (linkdef.empty()) {
4709 clingArgs.push_back(
"-Ietc/cling/cint");
4711 if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
4712 llvmResourceDir.c_str())) {
4714 rootclingRetCode += 1;
4724 }
else if (isSelXML) {
4728 std::ifstream
file(linkdefFilename.c_str());
4729 if (
file.is_open()) {
4733 if (!xmlr.
Parse(linkdefFilename.c_str(), selectionRules)) {
4746 std::ifstream
file(linkdefFilename.c_str());
4747 if (
file.is_open()) {
4757 clingArgs.push_back(
"-Ietc/cling/cint");
4759 if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
4760 llvmResourceDir.c_str())) {
4762 rootclingRetCode += 1;
4797 dictStream <<
"#include \"TBuffer.h\"\n"
4798 <<
"#include \"TVirtualObject.h\"\n"
4799 <<
"#include <vector>\n"
4800 <<
"#include \"TSchemaHelper.h\"\n\n";
4802 std::list<std::string> includes;
4804 for (
auto & incFile : includes) {
4805 dictStream <<
"#include <" << incFile <<
">" << std::endl;
4807 dictStream << std::endl;
4812 int scannerVerbLevel = 0;
4815 scannerVerbLevel = GetErrorIgnoreLevel() ==
kInfo;
4817 scannerVerbLevel = GetErrorIgnoreLevel() <
kWarning;
4840 scan.
Scan(CI->getASTContext());
4842 bool has_input_error =
false;
4849 !dictSelRulesPresent &&
4856 if (rootclingRetCode)
return rootclingRetCode;
4863 if (annRcd.RequestNoInputOperator()) {
4875 if (has_input_error) {
4885 for (
auto &&includedFromLinkdef : filesIncludedByLinkdef) {
4886 includeForSource +=
"#include \"" + includedFromLinkdef +
"\"\n";
4914 constructorTypes.emplace_back(
"TRootIOCtor", interp);
4915 constructorTypes.emplace_back(
"__void__", interp);
4916 constructorTypes.emplace_back(
"", interp);
4946 if (rootclingRetCode != 0) {
4947 return rootclingRetCode;
4966 std::string detectedUmbrella;
4967 for (
auto & arg : pcmArgs) {
4969 detectedUmbrella = arg;
4975 headersDeclsMap.clear();
4979 std::string headersClassesMapString =
"\"\"";
4980 std::string fwdDeclsString =
"\"\"";
4996 if (modGen.
IsPCH()) {
4999 if (!
CheckModuleValid(modGen, llvmResourceDir, interp, linkdefFilename, moduleName.str()))
5009 ofstream outputfile(liblist_filename.c_str(), ios::out);
5012 executableFileName, liblist_filename.c_str());
5014 const size_t endStr =
gLibsNeeded.find_last_not_of(
" \t");
5015 outputfile <<
gLibsNeeded.substr(0, endStr + 1) << endl;
5017 outputfile <<
"# Now the list of classes\n";
5022 outputfile << annRcd.GetNormalizedName() << endl;
5029 if (0 != rootclingRetCode)
return rootclingRetCode;
5035 [](
const std::string &
a,
const std::string &
b) -> std::string {
5036 if (a.empty()) return b;
5037 else return a +
" " + b;
5042 std::list<std::string> classesNames;
5043 std::list<std::string> classesNamesForRootmap;
5044 std::list<std::string> classesDefsList;
5048 classesNamesForRootmap,
5052 std::list<std::string> enumNames;
5057 std::list<std::string> varNames;
5062 if (0 != rootclingRetCode)
return rootclingRetCode;
5065 if (rootMapNeeded) {
5067 std::list<std::string> nsNames;
5076 rootmapLibName.c_str());
5079 std::unordered_set<std::string> headersToIgnore;
5082 headersToIgnore.insert(optHeaderFileName.c_str());
5084 std::list<std::string> typedefsRootmapLines;
5092 classesNamesForRootmap,
5094 typedefsRootmapLines,
5100 if (0 != rootclingRetCode)
return 1;
5110 cling::Interpreter::PushTransactionRAII RAII(&interp);
5111 CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
5122 if(rootclingRetCode == 0) {
5123 rootclingRetCode += tmpCatalog.
commit();
5128 return rootclingRetCode;
5139 unsigned int numberOfHeaders = 0;
5140 for (std::vector<std::string>::iterator it = headersNames.begin();
5141 it != headersNames.end(); ++it) {
5142 const std::string headername(*it);
5147 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5148 headername.c_str());
5151 return numberOfHeaders;
5157 unsigned int extractArgs(
int argc,
char **argv, std::vector<std::string> &args)
5160 unsigned int argvCounter = 0;
5161 for (
int i = 1; i < argc; ++i) {
5164 args.push_back(argv[i]);
5166 }
else if (argvCounter) {
5167 argv[i - argvCounter] = argv[i];
5174 std::cout <<
"Args: \n";
5175 for (std::vector<std::string>::iterator it = args.begin();
5176 it < args.end(); ++it) {
5177 std::cout << i <<
") " << *it << std::endl;
5191 if (std::string::npos !=
result) {
5203 const unsigned int size(str.size());
5204 char *
a =
new char[
size + 1];
5206 memcpy(
a, str.c_str(),
size);
5222 std::vector<std::string> &ofilesnames)
5224 ofilesnames.reserve(headersNames.size());
5226 for (std::vector<std::string>::const_iterator it = headersNames.begin();
5227 it != headersNames.end(); ++it) {
5228 std::string ofilename(*it);
5230 ofilesnames.push_back(ofilename);
5237 const std::vector<std::string> &argsToBeAdded,
5238 const std::string &optName =
"")
5240 for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
5241 it != argsToBeAdded.end(); ++it) {
5249 const std::vector<std::string> &argsToBeAdded,
5250 const std::string &optName =
"")
5252 for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
5253 it != argsToBeAdded.end(); ++it) {
5254 if (optName.length()) {
5264 const std::string &selectionFileName,
5265 const std::string &targetLibName,
5267 const std::vector<std::string> &pcmsNames,
5268 const std::vector<std::string> &includes,
5269 const std::vector<std::string> &preprocDefines,
5270 const std::vector<std::string> &preprocUndefines,
5271 const std::vector<std::string> &warnings,
5272 const std::string &rootmapFileName,
5273 const std::string &rootmapLibName,
5274 bool interpreteronly,
5277 bool writeEmptyRootPCM,
5279 bool noIncludePaths,
5280 bool noGlobalUsingStd,
5281 const std::vector<std::string> &headersNames,
5282 bool failOnWarnings,
5283 const std::string &ofilename)
5287 std::vector<char *> argvVector;
5298 std::string dictLocation;
5304 std::string newRootmapLibName(rootmapLibName);
5305 if (!rootmapFileName.empty() && newRootmapLibName.empty()) {
5306 if (headersNames.size() != 1) {
5308 "*** genreflex: No rootmap lib and several header specified!\n");
5311 newRootmapLibName =
"lib";
5312 newRootmapLibName += cleanHeaderName;
5318 std::string newRootmapFileName(rootmapFileName);
5319 if (!newRootmapFileName.empty() && !
HasPath(newRootmapFileName)) {
5320 newRootmapFileName = dictLocation + newRootmapFileName;
5325 if (!newRootmapFileName.empty()) {
5331 if (!newRootmapLibName.empty()) {
5337 if (interpreteronly)
5345 if (!targetLibName.empty()) {
5355 if (noGlobalUsingStd)
5365 if (writeEmptyRootPCM)
5388 if (!selectionFileName.empty()) {
5392 const int argc = argvVector.size();
5396 std::cout <<
"Rootcling commandline:\n";
5397 for (
int i = 0; i < argc; i++)
5398 std::cout << i <<
") " << argvVector[i] << std::endl;
5401 char **argv = & (argvVector[0]);
5406 for (
int i = 0; i < argc; i++)
5407 delete [] argvVector[i];
5409 return rootclingReturnCode;
5418 const std::string &selectionFileName,
5419 const std::string &targetLibName,
5421 const std::vector<std::string> &pcmsNames,
5422 const std::vector<std::string> &includes,
5423 const std::vector<std::string> &preprocDefines,
5424 const std::vector<std::string> &preprocUndefines,
5425 const std::vector<std::string> &warnings,
5426 const std::string &rootmapFileName,
5427 const std::string &rootmapLibName,
5428 bool interpreteronly,
5431 bool writeEmptyRootPCM,
5433 bool noIncludePaths,
5434 bool noGlobalUsingStd,
5435 const std::vector<std::string> &headersNames,
5436 bool failOnWarnings,
5437 const std::string &outputDirName_const =
"")
5439 std::string outputDirName(outputDirName_const);
5441 std::vector<std::string> ofilesNames;
5448 std::vector<std::string> namesSingleton(1);
5449 for (
unsigned int i = 0; i < headersNames.size(); ++i) {
5450 namesSingleton[0] = headersNames[i];
5451 std::string ofilenameFullPath(ofilesNames[i]);
5452 if (llvm::sys::path::parent_path(ofilenameFullPath) ==
"")
5453 ofilenameFullPath = outputDirName + ofilenameFullPath;
5475 if (returnCode != 0)
5490 std::vector<std::string> &values)
5493 if (options[oIndex]) {
5494 const int nVals = options[oIndex].count();
5495 values.reserve(nVals);
5496 int optionIndex = 0;
5499 << optionIndex <<
"/" << nVals <<
" "
5500 << opt->arg << std::endl;
5502 values.push_back(opt->arg);
5513 const char *descriptor)
5515 if (options[optionIndex]) {
5517 "*** genereflex: %s is not supported anymore.\n",
5574 enum optionIndex { UNKNOWN,
5605 enum optionTypes { NOTYPE, STRING } ;
5608 const char *genreflexUsage =
5609 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5610 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5613 const char *selectionFilenameUsage =
5614 "-s, --selection_file\tSelection filename\n"
5615 " Class selection file to specify for which classes the dictionary\n"
5616 " will be generated. The final set can be crafted with exclusion and\n"
5617 " exclusion rules.\n"
5618 " Properties can be specified. Some have special meaning:\n"
5619 " - name [string] name of the entity to select with an exact matching\n"
5620 " - pattern [string] name with wildcards (*) to select entities\n"
5621 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5622 " file where the C++ entities reside and not to C++ entities themselves.\n"
5623 " - transient/persistent [string: true/false] The fields to which they are\n"
5624 " applied will not be persistified if requested.\n"
5625 " - comment [string]: what you could write in code after an inline comment\n"
5626 " without \"//\". For example comment=\"!\" or \"||\".\n"
5627 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5628 " Default value is 'false'\n"
5629 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5630 " to 'true'. Default value is 'false'\n"
5634 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5635 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5636 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5637 " [noInputOperator=\"true/false\"] />\n"
5638 " <class name=\"classname\" >\n"
5639 " <field name=\"m_transient\" transient=\"true\"/>\n"
5640 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5641 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5642 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5644 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5645 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5646 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5649 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5650 " <method name=\"unwanted\" />\n"
5655 " If no selection file is specified, the class with the filename without\n"
5656 " extension will be selected, i.e. myClass.h as argument without any\n"
5657 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5659 const char *outputFilenameUsage =
5660 "-o, --output\tOutput filename\n"
5661 " Output file name. If an existing directory is specified instead of a file,\n"
5662 " then a filename will be built using the name of the input file and will\n"
5663 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5664 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5665 " have unique names.\n";
5668 const char *targetLib =
5669 "-l, --library\tTarget library\n"
5670 " The flag -l must be followed by the name of the library that will\n"
5671 " contain the object file corresponding to the dictionary produced by\n"
5672 " this invocation of genreflex.\n"
5673 " The name takes priority over the one specified for the rootmapfile.\n"
5674 " The name influences the name of the created pcm:\n"
5675 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5676 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5677 " Any \"liblib\" occurence is transformed in the expected \"lib\".\n"
5678 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5679 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5681 const char *rootmapUsage =
5682 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5683 " This file lists the autoload keys. For example classes for which the\n"
5684 " reflection information is provided.\n"
5685 " The format of the rootmap is the following:\n"
5686 " - Forward declarations section\n"
5687 " - Libraries sections\n"
5688 " Rootmaps can be concatenated together, for example with the cat util.\n"
5689 " In order for ROOT to pick up the information in the rootmaps, they\n"
5690 " have to be located in the library path and have the .rootmap extension.\n"
5691 " An example rootmap file could be:\n"
5693 " template <class T> class A;\n"
5694 " [ libMyLib.so ]\n"
5695 " class A<double>\n"
5700 const char *rootmapLibUsage =
5701 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5734 "--multiDict\tSupport for many dictionaries in one library\n"
5735 " Form correct pcm names if multiple dictionaries will be in the same\n"
5736 " library (needs target library switch. See its documentation).\n"
5743 "" ,
"noGlobalUsingStd" ,
5745 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5746 " All header files must have sumbols from std:: namespace fully qualified\n"
5752 "s" ,
"selection_file" ,
5754 selectionFilenameUsage
5768 "" ,
"rootmap-lib" ,
5776 "" ,
"interpreteronly",
5778 "--interpreteronly\tDo not generate I/O related information.\n"
5779 " Generate minimal dictionary required for interactivity.\n"
5787 "--split\tSplit the dictionary\n"
5788 " Split in two the dictionary, isolating the part with\n"
5789 " ClassDef related functions in a separate file.\n"
5797 "-m \tPcm file loaded before any header (option can be repeated).\n"
5805 "-v, --verbose\tPrint some debug information.\n"
5813 "--debug\tPrint all debug information.\n"
5821 "--quiet\tPrint only warnings and errors (default).\n"
5829 "--silent\tPrint no information at all.\n"
5835 "" ,
"writeEmptyPCM",
5837 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5845 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5854 "--help\tPrint usage and exit.\n"
5860 "",
"fail_on_warnings",
5862 "--fail_on_warnings\tFail on warnings and errors.\n"
5868 "",
"selSyntaxOnly",
5870 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5876 "" ,
"noIncludePaths",
5878 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5917 "" ,
"no_membertypedefs" ,
5925 "" ,
"no_templatetypedefs" ,
5930 {0, 0,
nullptr,
nullptr,
nullptr,
nullptr}
5933 std::vector<std::string> headersNames;
5934 const int originalArgc = argc;
5936 const int extractedArgs = extractArgs(argc, argv, headersNames);
5939 argc -=
offset + extractedArgs;
5944 std::vector<ROOT::option::Option> options(stats.
options_max);
5945 std::vector<ROOT::option::Option> buffer(stats.
buffer_max);
5951 if (parse.
error()) {
5957 if (options[HELP] || originalArgc == 1) {
5962 int numberOfHeaders = checkHeadersNames(headersNames);
5963 if (0 == numberOfHeaders) {
5974 std::string verbosityOption(
"-v2");
5975 if (options[SILENT]) verbosityOption =
"-v0";
5976 if (options[VERBOSE] || getenv (
"VERBOSE")) verbosityOption =
"-v3";
5977 if (options[
DEBUG]) verbosityOption =
"-v4";
5982 std::string selectionFileName;
5983 if (options[SELECTIONFILENAME]) {
5984 selectionFileName = options[SELECTIONFILENAME].arg;
5987 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
5988 selectionFileName.c_str());
6003 std::string rootmapFileName(options[ROOTMAP].arg ? options[ROOTMAP].arg :
"");
6004 std::string rootmapLibName(options[ROOTMAPLIB].arg ? options[ROOTMAPLIB].arg :
"");
6007 std::string targetLibName;
6008 if (options[TARGETLIB]) {
6009 targetLibName = options[TARGETLIB].arg;
6012 "Invalid target library extension: filename is %s and extension %s is expected!\n",
6013 targetLibName.c_str(),
6017 if (options[ROOTMAP]) {
6022 bool isCxxmodule = options[CXXMODULE];
6024 bool multidict =
false;
6025 if (options[MULTIDICT]) multidict =
true;
6027 bool noGlobalUsingStd =
false;
6028 if (options[NOGLOBALUSINGSTD]) noGlobalUsingStd =
true;
6030 if (multidict && targetLibName.empty()) {
6032 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
6036 bool interpreteronly =
false;
6037 if (options[INTERPRETERONLY])
6038 interpreteronly =
true;
6040 bool doSplit =
false;
6044 bool writeEmptyRootPCM =
false;
6045 if (options[WRITEEMPTYROOTPCM])
6046 writeEmptyRootPCM =
true;
6048 bool selSyntaxOnly =
false;
6049 if (options[SELSYNTAXONLY]) {
6050 selSyntaxOnly =
true;
6053 bool noIncludePaths =
false;
6054 if (options[NOINCLUDEPATHS]) {
6055 noIncludePaths =
true;
6058 bool failOnWarnings =
false;
6059 if (options[FAILONWARNINGS]) {
6060 failOnWarnings =
true;
6069 std::vector<std::string> pcmsNames;
6073 std::vector<std::string> preprocDefines;
6077 std::vector<std::string> preprocUndefines;
6081 std::vector<std::string> includes;
6085 std::vector<std::string> warnings;
6096 int returnValue = 0;
6097 std::string ofileName(options[OFILENAME] ? options[OFILENAME].arg :
"");
6101 if (!ofileName.empty() && !llvm::sys::fs::is_directory(ofileName)) {
6102 returnValue = invokeRootCling(verbosityOption,
6125 returnValue = invokeManyRootCling(verbosityOption,
6158 assert(!
gDriverConfig &&
"Driver configuration already set!");
6178 if (std::string::npos != exeName.find(
"genreflex"))
6186 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
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 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
const AttributesMap_t & GetAttributes() const
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 std::list< VariableSelectionRule > & GetFieldSelectionRules() const
bool LoadIncludes(std::string &extraInclude)
bool Parse(SelectionRules &sr, llvm::StringRef code, const std::vector< std::string > &parserArgs, const char *llvmdir)
void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
void WriteClassInit(std::ostream &strm, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const ROOT::TMetaUtils::RConstructorTypes &, bool &needCollectionProxy, void(*emitStreamerInfo)(const char *))
void WriteUmbrellaHeader(std::ostream &out) const
Write a header file pulling in the content of this module through a series of #defined,...
const std::string & GetUmbrellaName() const
const std::vector< std::string > & GetIncludePaths() const
void WriteRegistrationSource(std::ostream &out, const std::string &fwdDeclnArgsToKeepString, const std::string &headersClassesMapString, const std::string &fwdDeclsString, const std::string &extraIncludes, bool hasCxxModule) const
const std::vector< std::string > & GetHeaders() const
void WriteContentHeader(std::ostream &out) const
Write a header file describing the content of this module through a series of variables inside the na...
int GetErrorCount() const
const std::string & GetModuleFileName() const
std::ostream & WritePPUndefines(std::ostream &out) const
Write #ifdef FOO # undef FOO #endif
void ParseArgs(const std::vector< std::string > &args)
Parse -I -D -U headers.h SomethingLinkdef.h.
const std::string & GetContentName() const
std::ostream & WritePPDefines(std::ostream &out) const
Write #ifndef FOO # define FOO=bar #endif
A parsed option from the command line together with its argument if it has one.
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
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.
bool AreAllSelectionRulesUsed() const
bool SearchNames(cling::Interpreter &interp)
void PrintSelectionRules() const
unsigned int Size() const
void SetSelectionFileType(ESelectionFileTypes fileType)
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)
void InclusionDirective(clang::SourceLocation, const clang::Token &, llvm::StringRef FileName, bool IsAngled, clang::CharSourceRange, const clang::FileEntry *, llvm::StringRef, llvm::StringRef, const clang::Module *, clang::SrcMgr::CharacteristicKind) override
bool Parse(const std::string &fileName, SelectionRules &out)
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.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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 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, const std::string &ofilename)
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, const std::string &outputDirName_const="")
Get the right ofilenames and invoke several times rootcling One invokation per header.
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 ...
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.
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))
int GenerateFullDict(std::ostream &dictStream, cling::Interpreter &interp, RScanner &scan, const ROOT::TMetaUtils::RConstructorTypes &ctorTypes, bool isSplit, bool isGenreflex, bool writeEmptyRootPCM)
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.
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))
static llvm::cl::list< std::string > gOptDictionaryHeaderFiles(llvm::cl::Positional, llvm::cl::ZeroOrMore, llvm::cl::desc("<list of dictionary header files> <LinkDef file>"), 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)
static llvm::cl::opt< bool > gOptReflex("reflex", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
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)
std::map< std::string, std::list< std::string > > HeadersDeclsMap_t
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))
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)
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)
cling::Interpreter *(* fTCling__GetInterpreter)()
bool(* fCloseStreamerInfoROOTFile)(bool writeEmptyRootPCM)
void(* fAddEnumToROOTFile)(const char *tdname)
void(* fInitializeStreamerInfoROOTFile)(const char *filename)
const char *(* fTROOT__GetIncludeDir)()
void(* fAddTypedefToROOTFile)(const char *tdname)
const char *(* fTROOT__GetEtcDir)()
void(* fAddStreamerInfoToROOTFile)(const char *normName)
const char ***(* fTROOT__GetExtraInterpreterArgs)()
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Describes an option, its help text (usage) and how it should be parsed.
static option::ArgStatus Required(const option::Option &option, bool msg)
Determines the minimum lengths of the buffer and options arrays used for Parser.
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
#define dest(otri, vertexptr)