12 "Usage: rootcling [-v][-v0-4] [-f] [out.cxx] [opts] "
13 "file1.h[+][-][!] file2.h[+][-][!] ...[LinkDef.h]\n";
18#include "rootclingCommandLineOptionsHelp.h"
20#include "RConfigure.h"
38#include <unordered_map>
39#include <unordered_set>
51#define PATH_MAX _MAX_PATH
59#include <mach-o/dyld.h>
68#include "cling/Interpreter/Interpreter.h"
69#include "cling/Interpreter/InterpreterCallbacks.h"
70#include "cling/Interpreter/LookupHelper.h"
71#include "cling/Interpreter/Value.h"
72#include "clang/AST/CXXInheritance.h"
73#include "clang/Basic/Diagnostic.h"
74#include "clang/Basic/MemoryBufferCache.h"
75#include "clang/Frontend/CompilerInstance.h"
76#include "clang/Frontend/FrontendActions.h"
77#include "clang/Frontend/FrontendDiagnostic.h"
78#include "clang/Lex/HeaderSearch.h"
79#include "clang/Lex/Preprocessor.h"
80#include "clang/Lex/ModuleMap.h"
81#include "clang/Lex/Pragma.h"
82#include "clang/Sema/Sema.h"
83#include "clang/Serialization/ASTWriter.h"
84#include "cling/Utils/AST.h"
86#include "llvm/Bitcode/BitstreamWriter.h"
87#include "llvm/Support/CommandLine.h"
88#include "llvm/Support/Path.h"
89#include "llvm/Support/PrettyStackTrace.h"
90#include "llvm/Support/Signals.h"
114#include <mach-o/dyld.h>
119#define strcasecmp _stricmp
120#define strncasecmp _strnicmp
146static llvm::cl::opt<bool>
148 llvm::cl::desc(
"Deprecated. Similar to -f but it ignores the dictionary generation. \
149When -r is present rootcling becomes a tool to generate rootmaps (and capability files)."),
169static void EmitTypedefs(
const std::vector<const clang::TypedefNameDecl *> &tdvec)
173 for (
const auto td : tdvec)
176static void EmitEnums(
const std::vector<const clang::EnumDecl *> &enumvec)
180 for (
const auto en : enumvec) {
182 if (clang::isa<clang::TranslationUnitDecl>(en->getDeclContext())
183 || clang::isa<clang::LinkageSpecDecl>(en->getDeclContext())
184 || clang::isa<clang::NamespaceDecl>(en->getDeclContext()))
194 static std::string exepath;
197 exepath = _dyld_get_image_name(0);
199#if defined(__linux) || defined(__linux__)
200 char linkname[PATH_MAX];
206 snprintf(linkname, PATH_MAX,
"/proc/%i/exe", pid);
207 int ret = readlink(linkname, buf, 1024);
208 if (ret > 0 && ret < 1024) {
214 char *buf =
new char[MAX_MODULE_NAME32 + 1];
217 while ((p = strchr(p,
'\\')))
223 return exepath.c_str();
229 const cling::Interpreter &interp)
237 const std::list<VariableSelectionRule> &fieldSelRules)
245 if (fieldSelRules.empty())
return;
247 clang::ASTContext &
C = decl.getASTContext();
248 clang::SourceRange commentRange;
250 const std::string declName(decl.getNameAsString());
252 for (std::list<VariableSelectionRule>::const_iterator it = fieldSelRules.begin();
253 it != fieldSelRules.end(); ++it) {
255 if (declName == varName) {
258 BaseSelectionRule::AttributesMap_t::iterator iter;
259 std::string userDefinedProperty;
260 for (iter = attrMap.begin(); iter != attrMap.end(); ++iter) {
261 const std::string &
name = iter->first;
262 const std::string &value = iter->second;
270 (decl.getType()->isArrayType() || decl.getType()->isPointerType())) {
271 const char *msg =
"Data member \"%s\" is an array or a pointer. "
272 "It is not possible to assign to it the iotype \"%s\". "
273 "This transformation is possible only with data members "
274 "which are not pointers or arrays.\n";
276 msg, varName.c_str(), value.c_str());
285 decl.addAttr(
new(
C) clang::AnnotateAttr(commentRange,
C, value, 0));
295 decl.addAttr(
new(
C) clang::AnnotateAttr(commentRange,
C,
"!", 0));
303 decl.addAttr(
new(
C) clang::AnnotateAttr(commentRange,
C, userDefinedProperty, 0));
314 cling::Interpreter &interpreter,
322 using namespace clang;
323 SourceLocation commentSLoc;
326 ASTContext &
C = CXXRD.getASTContext();
327 Sema &
S = interpreter.getCI()->getSema();
329 SourceRange commentRange;
332 clang::Decl *declBaseClassPtr =
static_cast<clang::Decl *
>(&CXXRD);
333 auto declSelRulePair = declSelRulesMap.
find(declBaseClassPtr->getCanonicalDecl());
334 if (declSelRulePair == declSelRulesMap.end()){
335 const std::string thisClassName(CXXRD.getName());
336 ROOT::TMetaUtils::Error(
"AnnotateDecl",
"Cannot find class %s in the list of selected classes.\n",thisClassName.c_str());
341 if (thisClassBaseSelectionRule) {
344 BaseSelectionRule::AttributesMap_t::iterator iter;
345 std::string userDefinedProperty;
346 for (
auto const & attr : thisClassBaseSelectionRule->
GetAttributes()) {
347 const std::string &
name = attr.first;
349 const std::string &value = attr.second;
352 CXXRD.addAttr(
new(
C) AnnotateAttr(commentRange,
C, userDefinedProperty, 0));
359 for (CXXRecordDecl::decl_iterator
I = CXXRD.decls_begin(),
360 E = CXXRD.decls_end();
I !=
E; ++
I) {
364 if (!(*I)->isImplicit()
365 && (isa<CXXMethodDecl>(*
I) || isa<FieldDecl>(*
I) || isa<VarDecl>(*
I))) {
369 SourceLocation maybeMacroLoc = (*I)->getLocation();
370 bool isClassDefMacro = maybeMacroLoc.isMacroID() &&
S.findMacroSpelling(maybeMacroLoc,
"ClassDef");
371 if (isClassDefMacro) {
372 while (isa<NamedDecl>(*
I) && cast<NamedDecl>(*I)->getName() !=
"DeclFileLine") {
381 commentRange = SourceRange(commentSLoc, commentSLoc.getLocWithOffset(
comment.size()));
383 if (isClassDefMacro) {
384 CXXRD.addAttr(
new(
C) AnnotateAttr(commentRange,
C,
comment.str(), 0));
385 }
else if (!isGenreflex) {
391 (*I)->addAttr(
new(
C) AnnotateAttr(commentRange,
C,
comment.str(), 0));
396 if (isGenreflex && thisClassSelectionRule != 0) {
400 if (FieldDecl *fieldDecl = dyn_cast<FieldDecl>(*
I)) {
412 llvm::APInt len = arrayType->getSize();
413 while (
const clang::ConstantArrayType *subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual())) {
414 len *= subArrayType->getSize();
415 arrayType = subArrayType;
417 return len.getLimitedValue();
423 const cling::Interpreter &interp)
425 static const clang::CXXRecordDecl *TObject_decl
428 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
435 const cling::Interpreter &interp)
437 static const clang::CXXRecordDecl *TObject_decl
447 size_t len = strlen(filename);
449 if (strlen(filename) >= xmllen) {
450 return (0 == strcasecmp(filename + (len - xmllen),
".xml"));
476 if (exepath && *exepath) {
478 char *ep =
new char[PATH_MAX];
479 if (!realpath(exepath, ep)) {
480 fprintf(stderr,
"rootcling: error getting realpath of rootcling!");
481 strlcpy(ep, exepath, PATH_MAX);
484 int nche = strlen(exepath) + 1;
485 char *ep =
new char[nche];
486 strlcpy(ep, exepath, nche);
490 if ((
s = strrchr(ep,
'/'))) {
492 int removesubdirs = 2;
493 if (!strncmp(
s + 1,
"rootcling_stage1.exe", 20)) {
497 }
else if (!strncmp(
s + 1,
"rootcling_stage1", 16)) {
502 for (
int i = 1;
s && i < removesubdirs; ++i) {
504 s = strrchr(ep,
'/');
518 int ncha = strlen(ep) + 10;
519 char *env =
new char[ncha];
520 snprintf(env, ncha,
"ROOTSYS=%s", ep);
541 const char *expectedTokens[],
545 if (
line[0] !=
'#')
return false;
547 for (
const char **iToken = expectedTokens; *iToken; ++iToken) {
548 while (isspace(
line[pos])) ++pos;
549 size_t lenToken = strlen(*iToken);
550 if (
line.compare(pos, lenToken, *iToken)) {
569 if (recordDecl->hasOwningModule()) {
570 clang::Module *M = recordDecl->getOwningModule()->getTopLevelModule();
573 std::string qual_name;
579 if (need.length() &&
gLibsNeeded.find(need) == string::npos) {
588 if (classname.find(
':') == std::string::npos)
return;
591 int slen = classname.size();
592 for (
int k = 0; k < slen; ++k) {
593 if (classname[k] ==
':') {
594 if (k + 1 >= slen || classname[k + 1] !=
':') {
599 string base = classname.substr(0, k);
604 autoloads[base] =
"";
608 }
else if (classname[k] ==
'<') {
620 std::string classname;
624 if (
line.find(
"Library.") != 0)
continue;
626 int pos =
line.find(
":", 8);
627 classname =
line.substr(8, pos - 8);
633 while (
line[0] ==
' ')
line.replace(0, 1,
"");
637 if (classname ==
"ROOT::TImpProxy") {
641 autoloads[classname] =
line;
656 const std::unordered_map<char, unsigned int> keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
659 if (
line ==
"{ decls }") {
661 if (
line[0] ==
'[')
break;
664 const char firstChar =
line[0];
665 if (firstChar ==
'[') {
667 libs =
line.substr(1,
line.find(
']') - 1);
668 while (libs[0] ==
' ') libs.replace(0, 1,
"");
669 }
else if (0 != keyLenMap.count(firstChar)) {
670 unsigned int keyLen = keyLenMap.at(firstChar);
671 keyname =
line.substr(keyLen,
line.length() - keyLen);
673 autoloads[keyname] = libs;
683void LoadLibraryMap(
const std::string &fileListName, map<string, string> &autoloads)
685 std::ifstream filelist(fileListName.c_str());
687 std::string filename;
690 while (filelist >> filename) {
692 if (llvm::sys::fs::is_directory(filename))
continue;
694 ifstream
file(filename.c_str());
698 bool new_format = (
line[0] ==
'[' ||
line[0] ==
'{') ;
700 file.seekg(0, std::ios::beg);
721 const string &fullname,
722 const clang::RecordDecl *cl,
723 cling::Interpreter &interp)
726 const clang::FunctionDecl *method
731 clang::TranslationUnitDecl *TU =
732 cl->getASTContext().getTranslationUnitDecl();
736 bool has_input_error =
false;
737 if (method != 0 && (method->getAccess() == clang::AS_public || method->getAccess() == clang::AS_none)) {
739 if (strstr(filename.c_str(),
"TBuffer.h") != 0 ||
740 strstr(filename.c_str(),
"Rtypes.h") != 0) {
742 has_input_error =
true;
745 has_input_error =
true;
747 if (has_input_error) {
749 const char *maybeconst =
"";
750 const char *mayberef =
"&";
751 if (
what[strlen(
what) - 1] ==
'<') {
752 maybeconst =
"const ";
756 "in this version of ROOT, the option '!' used in a linkdef file\n"
757 " implies the actual existence of customized operators.\n"
758 " The following declaration is now required:\n"
759 " TBuffer &%s(TBuffer &,%s%s *%s);\n",
what, maybeconst, fullname.c_str(), mayberef);
761 return has_input_error;
773 int ncha = fullname.length() + 13;
774 char *
proto =
new char[ncha];
786 return has_input_error;
792bool CheckClassDef(
const clang::RecordDecl &cl,
const cling::Interpreter &interp)
798 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
802 bool isAbstract = clxx->isAbstract();
805 std::string qualName;
807 const char *qualName_c = qualName.c_str();
809 "because it inherits from TObject but does not "
810 "have its own ClassDef.\n",
823 if (
m.getType().isConstQualified()) {
824 string ret =
"const_cast< ";
827 if (type_name.substr(0,6)==
"const ") {
828 ret += type_name.c_str()+6;
834 ret +=
m.getName().str();
838 return prefix +
m.getName().str();
848 const cling::Interpreter &interp,
850 std::ostream &dictStream)
853 std::string mTypename;
866 if (clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
868 const clang::ClassTemplateSpecializationDecl *tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (clxx);
869 if (!tmplt_specialization)
return 0;
876 string fulName1, fulName2;
877 const char *tcl1 = 0, *tcl2 = 0;
878 const clang::TemplateArgument &arg0(tmplt_specialization->getTemplateArgs().get(0));
879 clang::QualType ti = arg0.getAsType();
883 fulName1 = ti.getAsString();
886 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
887 clang::QualType tmplti = arg1.getAsType();
890 fulName2 = tmplti.getAsString();
897 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
903 if (arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
907 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
909 }
else if (
m.getType()->isPointerType()) {
914 dictStream <<
" {" << std::endl;
916 dictStream <<
" for (Int_t R__l = 0; R__l < " << len <<
"; R__l++) {" << std::endl;
921 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
";" << std::endl;
924 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
"[R__l];" << std::endl;
927 dictStream <<
" delete *" << stlName.c_str() <<
";" << std::endl
928 <<
" *" << stlName.c_str() <<
" = new " << stlType.c_str() <<
";" << std::endl
929 <<
" " << stlType.c_str() <<
" &R__stl = **" << stlName.c_str() <<
";" << std::endl;
932 dictStream <<
" delete " << stlName.c_str() <<
"[R__l];" << std::endl
933 <<
" " << stlName.c_str() <<
"[R__l] = new " << stlType.c_str() <<
";" << std::endl
934 <<
" " << stlType.c_str() <<
" &R__stl = *" << stlName.c_str() <<
"[R__l];" << std::endl;
938 dictStream <<
" R__stl.clear();" << std::endl;
941 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() <<
"));" << std::endl
942 <<
" if (R__tcl1==0) {" << std::endl
943 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
944 << fulName1.c_str() <<
"!\");" << std::endl
945 <<
" return;" << std::endl
946 <<
" }" << std::endl;
949 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() <<
"));" << std::endl
950 <<
" if (R__tcl2==0) {" << std::endl
951 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
952 << fulName2.c_str() <<
"!\");" << std::endl
953 <<
" return;" << std::endl
954 <<
" }" << std::endl;
957 dictStream <<
" int R__i, R__n;" << std::endl
958 <<
" R__b >> R__n;" << std::endl;
961 dictStream <<
" R__stl.reserve(R__n);" << std::endl;
963 dictStream <<
" for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
967 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
987 std::string keyName(ti.getAsString());
988 dictStream <<
" typedef " << keyName <<
" Value_t;" << std::endl
989 <<
" std::pair<Value_t const, " << tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() <<
" > R__t3(R__t,R__t2);" << std::endl
990 <<
" R__stl.insert(R__t3);" << std::endl;
998 dictStream <<
" R__stl.insert(R__t);" << std::endl;
1003 dictStream <<
" R__stl.push_back(R__t);" << std::endl;
1006 dictStream <<
" R__stl.push_front(R__t);" << std::endl;
1011 dictStream <<
" }" << std::endl
1012 <<
" }" << std::endl;
1013 if (isArr) dictStream <<
" }" << std::endl;
1019 dictStream <<
" for (Int_t R__l = 0; R__l < " << len <<
"; R__l++) {" << std::endl;
1021 dictStream <<
" {" << std::endl;
1024 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
";" << std::endl;
1027 dictStream <<
" " << stlType.c_str() <<
" &R__stl = " << stlName.c_str() <<
"[R__l];" << std::endl;
1030 dictStream <<
" " << stlType.c_str() <<
" &R__stl = **" << stlName.c_str() <<
";" << std::endl;
1033 dictStream <<
" " << stlType.c_str() <<
" &R__stl = *" << stlName.c_str() <<
"[R__l];" << std::endl;
1037 dictStream <<
" int R__n=int(R__stl.size());" << std::endl
1038 <<
" R__b << R__n;" << std::endl
1039 <<
" if(R__n) {" << std::endl;
1042 dictStream <<
" TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() <<
"));" << std::endl
1043 <<
" if (R__tcl1==0) {" << std::endl
1044 <<
" Error(\"" << stlName.c_str() <<
" streamer\",\"Missing the TClass object for "
1045 << fulName1.c_str() <<
"!\");" << std::endl
1046 <<
" return;" << std::endl
1047 <<
" }" << std::endl;
1050 dictStream <<
" TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() <<
"));" << std::endl
1051 <<
" if (R__tcl2==0) {" << std::endl
1052 <<
" Error(\"" << stlName.c_str() <<
"streamer\",\"Missing the TClass object for " << fulName2.c_str() <<
"!\");" << std::endl
1053 <<
" return;" << std::endl
1054 <<
" }" << std::endl;
1057 dictStream <<
" " << stlType.c_str() <<
"::iterator R__k;" << std::endl
1058 <<
" for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
1060 const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
1061 clang::QualType tmplti = arg1.getAsType();
1068 dictStream <<
" }" << std::endl
1069 <<
" }" << std::endl
1070 <<
" }" << std::endl;
1071 if (isArr) dictStream <<
" }" << std::endl;
1083 std::string mTypenameStr;
1087 if (!strcmp(mTypeName,
"string")) {
1089 std::string fieldname =
m.getName().str();
1092 if (
m.getType()->isConstantArrayType()) {
1093 if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1094 dictStream <<
"// Array of pointer to std::string are not supported (" << fieldname <<
"\n";
1096 std::stringstream fullIdx;
1097 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1100 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1101 << arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1102 fullIdx <<
"[R__i" << dim <<
"]";
1103 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1106 dictStream <<
" { TString R__str; R__str.Streamer(R__b); "
1107 << fieldname << fullIdx.str() <<
" = R__str.Data();}" << std::endl;
1110 dictStream <<
" { TString R__str; R__str.Streamer(R__b); ";
1111 if (
m.getType()->isPointerType())
1112 dictStream <<
"if (*" << fieldname <<
") delete *" << fieldname <<
"; (*"
1113 << fieldname <<
" = new string(R__str.Data())); }" << std::endl;
1115 dictStream << fieldname <<
" = R__str.Data(); }" << std::endl;
1119 if (
m.getType()->isPointerType())
1120 dictStream <<
" { TString R__str; if (*" << fieldname <<
") R__str = (*"
1121 << fieldname <<
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
1122 else if (
m.getType()->isConstantArrayType()) {
1123 std::stringstream fullIdx;
1124 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
1127 dictStream <<
" for (int R__i" << dim <<
"=0; R__i" << dim <<
"<"
1128 << arrayType->getSize().getLimitedValue() <<
"; ++R__i" << dim <<
" )" << std::endl;
1129 fullIdx <<
"[R__i" << dim <<
"]";
1130 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1133 dictStream <<
" { TString R__str(" << fieldname << fullIdx.str() <<
".c_str()); R__str.Streamer(R__b);}" << std::endl;
1135 dictStream <<
" { TString R__str = " << fieldname <<
".c_str(); R__str.Streamer(R__b);}" << std::endl;
1146 if (
m.getType()->isPointerType()) {
1147 if (
m.getType()->getPointeeType()->isPointerType()) {
1159 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1161 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1163 dictStream <<
"[0]";
1164 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1179 int enclSpaceNesting = 0;
1186 dictStream <<
"#include \"TInterpreter.h\"\n";
1188 dictStream <<
"//_______________________________________"
1189 <<
"_______________________________________" << std::endl;
1190 if (add_template_keyword) dictStream <<
"template <> ";
1191 dictStream <<
"atomic_TClass_ptr " << clsname <<
"::fgIsA(0); // static to hold class pointer" << std::endl
1194 <<
"//_______________________________________"
1195 <<
"_______________________________________" << std::endl;
1196 if (add_template_keyword) dictStream <<
"template <> ";
1197 dictStream <<
"const char *" << clsname <<
"::Class_Name()" << std::endl <<
"{" << std::endl
1198 <<
" return \"" << fullname <<
"\";" << std::endl <<
"}" << std::endl << std::endl;
1200 dictStream <<
"//_______________________________________"
1201 <<
"_______________________________________" << std::endl;
1202 if (add_template_keyword) dictStream <<
"template <> ";
1203 dictStream <<
"const char *" << clsname <<
"::ImplFileName()" << std::endl <<
"{" << std::endl
1204 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1205 <<
"*)0x0)->GetImplFileName();" << std::endl <<
"}" << std::endl << std::endl
1207 <<
"//_______________________________________"
1208 <<
"_______________________________________" << std::endl;
1209 if (add_template_keyword) dictStream <<
"template <> ";
1210 dictStream <<
"int " << clsname <<
"::ImplFileLine()" << std::endl <<
"{" << std::endl
1211 <<
" return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1212 <<
"*)0x0)->GetImplFileLine();" << std::endl <<
"}" << std::endl << std::endl
1214 <<
"//_______________________________________"
1215 <<
"_______________________________________" << std::endl;
1216 if (add_template_keyword) dictStream <<
"template <> ";
1217 dictStream <<
"TClass *" << clsname <<
"::Dictionary()" << std::endl <<
"{" << std::endl;
1221 dictStream <<
" gInterpreter->AutoLoad(\"" << fullname <<
"\");\n";
1222 dictStream <<
" fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
1223 <<
"*)0x0)->GetClass();" << std::endl
1224 <<
" return fgIsA;\n"
1225 <<
"}" << std::endl << std::endl
1227 <<
"//_______________________________________"
1228 <<
"_______________________________________" << std::endl;
1229 if (add_template_keyword) dictStream <<
"template <> ";
1230 dictStream <<
"TClass *" << clsname <<
"::Class()" << std::endl <<
"{" << std::endl;
1232 dictStream <<
" Dictionary();\n";
1234 dictStream <<
" if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
1235 dictStream << fullname <<
"*)0x0)->GetClass(); }" << std::endl;
1237 dictStream <<
" return fgIsA;" << std::endl
1238 <<
"}" << std::endl << std::endl;
1240 while (enclSpaceNesting) {
1241 dictStream <<
"} // namespace " << nsname << std::endl;
1250 cling::Interpreter &interp,
1251 std::ostream &dictStream)
1253 if (cl->isAnonymousNamespace()) {
1265 if (classname !=
"ROOT") {
1269 dictStream <<
" namespace ROOTDict {" << std::endl;
1272 dictStream <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
1276 dictStream <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();" << std::endl;
1277 dictStream << std::endl
1279 <<
" // Function generating the singleton type initializer" << std::endl
1282 <<
" inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1283 <<
" {" << std::endl
1285 <<
" ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
1286 <<
" {" << std::endl
1289 <<
" static ::ROOT::TGenericClassInfo " << std::endl
1291 <<
" instance(\"" << classname.c_str() <<
"\", ";
1294 dictStream <<
"::" << classname.c_str() <<
"::Class_Version(), ";
1296 dictStream <<
"0 /*version*/, ";
1300 for (
unsigned int i = 0; i < filename.length(); i++) {
1301 if (filename[i] ==
'\\') filename[i] =
'/';
1304 <<
" ::ROOT::Internal::DefineBehavior((void*)0,(void*)0)," << std::endl
1308 dictStream <<
"&::" << classname.c_str() <<
"::Dictionary, ";
1310 dictStream <<
"&" << mappedname.c_str() <<
"_Dictionary, ";
1313 dictStream << 0 <<
");" << std::endl
1315 <<
" return &instance;" << std::endl
1316 <<
" }" << std::endl
1317 <<
" // Insure that the inline function is _not_ optimized away by the compiler\n"
1318 <<
" ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance; " << std::endl
1319 <<
" // Static variable to force the class initialization" << std::endl
1321 <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();"
1322 <<
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
1325 dictStream << std::endl <<
" // Dictionary for non-ClassDef classes" << std::endl
1326 <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary() {" << std::endl
1327 <<
" return GenerateInitInstance()->GetClass();" << std::endl
1328 <<
" }" << std::endl << std::endl;
1331 dictStream <<
" }" << std::endl;
1333 dictStream <<
"}" << std::endl;
1335 dictStream << std::endl;
1344llvm::StringRef
GrabIndex(
const clang::FieldDecl &member,
int printError)
1347 llvm::StringRef where;
1350 if (index.size() == 0 && printError) {
1351 const char *errorstring;
1354 errorstring =
"is not an integer";
1357 errorstring =
"has not been defined before the array";
1360 errorstring =
"is a private member of a parent class";
1363 errorstring =
"is not known";
1366 errorstring =
"UNKNOWN ERROR!!!!";
1369 if (where.size() == 0) {
1371 member.getParent()->getName().str().c_str(), member.getName().str().c_str());
1374 member.getParent()->getName().str().c_str(), member.getName().str().c_str(), where.str().c_str(), errorstring);
1383 const cling::Interpreter &interp,
1385 std::ostream &dictStream)
1387 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1388 if (clxx == 0)
return;
1395 int enclSpaceNesting = 0;
1401 dictStream <<
"//_______________________________________"
1402 <<
"_______________________________________" << std::endl;
1403 if (add_template_keyword) dictStream <<
"template <> ";
1404 dictStream <<
"void " << clsname <<
"::Streamer(TBuffer &R__b)" << std::endl <<
"{" << std::endl
1405 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl;
1413 int basestreamer = 0;
1414 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1418 string base_fullname;
1421 if (strstr(base_fullname.c_str(),
"::")) {
1423 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1424 <<
" typedef " << base_fullname <<
" baseClass" << basestreamer <<
";" << std::endl
1425 <<
" baseClass" << basestreamer <<
"::Streamer(R__b);" << std::endl;
1427 dictStream <<
" " << base_fullname <<
"::Streamer(R__b);" << std::endl;
1432 if (!basestreamer) {
1433 dictStream <<
" ::Error(\"" << fullname <<
"::Streamer\", \"version id <=0 in ClassDef,"
1434 " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
1436 dictStream <<
"}" << std::endl << std::endl;
1437 while (enclSpaceNesting) {
1438 dictStream <<
"} // namespace " << nsname.c_str() << std::endl;
1445 string classname = fullname;
1446 if (strstr(fullname.c_str(),
"::")) {
1448 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1449 <<
" typedef ::" << fullname <<
" thisClass;" << std::endl;
1450 classname =
"thisClass";
1452 for (
int i = 0; i < 2; i++) {
1457 dictStream <<
" UInt_t R__s, R__c;" << std::endl;
1458 dictStream <<
" if (R__b.IsReading()) {" << std::endl;
1459 dictStream <<
" Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
1461 dictStream <<
" R__b.CheckByteCount(R__s, R__c, " << classname.c_str() <<
"::IsA());" << std::endl;
1462 dictStream <<
" } else {" << std::endl;
1463 dictStream <<
" R__c = R__b.WriteVersion(" << classname.c_str() <<
"::IsA(), kTRUE);" << std::endl;
1468 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1472 string base_fullname;
1475 if (strstr(base_fullname.c_str(),
"::")) {
1477 dictStream <<
" //This works around a msvc bug and should be harmless on other platforms" << std::endl
1478 <<
" typedef " << base_fullname <<
" baseClass" << base <<
";" << std::endl
1479 <<
" baseClass" << base <<
"::Streamer(R__b);" << std::endl;
1482 dictStream <<
" " << base_fullname <<
"::Streamer(R__b);" << std::endl;
1488 for (clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
1493 clang::QualType
type = field_iter->getType();
1494 std::string type_name =
type.getAsString(clxx->getASTContext().getPrintingPolicy());
1504 if (strstr(type_name.c_str(),
"Float16_t")) isFloat16 = 1;
1508 if (strstr(type_name.c_str(),
"Double32_t")) isDouble32 = 1;
1511 if (strncmp(
comment,
"!", 1)) {
1514 if (underling_type->isFundamentalType() || underling_type->isEnumeralType()) {
1515 if (
type.getTypePtr()->isConstantArrayType() &&
1516 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1517 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1521 dictStream <<
" int R__i;" << std::endl;
1524 dictStream <<
" for (R__i = 0; R__i < " <<
s <<
"; R__i++)" << std::endl;
1526 ROOT::TMetaUtils::Error(0,
"*** Datamember %s::%s: array of pointers to fundamental type (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
1527 dictStream <<
" ;//R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1529 dictStream <<
" ;//R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1531 }
else if (
type.getTypePtr()->isPointerType()) {
1532 llvm::StringRef indexvar =
GrabIndex(**field_iter, i == 0);
1533 if (indexvar.size() == 0) {
1535 ROOT::TMetaUtils::Error(0,
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
1536 dictStream <<
" //R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1538 dictStream <<
" //R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);" << std::endl;
1542 dictStream <<
" delete [] " << field_iter->getName().str() <<
";" << std::endl
1547 <<
"," << indexvar.str() <<
");" << std::endl;
1548 }
else if (isDouble32) {
1550 <<
"," << indexvar.str() <<
");" << std::endl;
1553 <<
"," << indexvar.str() <<
");" << std::endl;
1557 dictStream <<
" R__b.WriteFastArrayFloat16("
1558 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1559 }
else if (isDouble32) {
1560 dictStream <<
" R__b.WriteFastArrayDouble32("
1561 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1563 dictStream <<
" R__b.WriteFastArray("
1564 << field_iter->getName().str() <<
"," << indexvar.str() <<
");" << std::endl;
1568 }
else if (
type.getTypePtr()->isArrayType()) {
1570 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1571 if (underling_type->isEnumeralType())
1572 dictStream <<
" R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() <<
");" << std::endl;
1576 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1577 }
else if (isDouble32) {
1579 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1582 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1586 if (underling_type->isEnumeralType()) {
1587 dictStream <<
" R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() <<
");" << std::endl;
1590 dictStream <<
" R__b.ReadStaticArrayFloat16(" << field_iter->getName().str() <<
");" << std::endl;
1591 }
else if (isDouble32) {
1592 dictStream <<
" R__b.ReadStaticArrayDouble32(" << field_iter->getName().str() <<
");" << std::endl;
1595 <<
"*)" << field_iter->getName().str() <<
");" << std::endl;
1600 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1603 if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
1604 if (underling_type->isEnumeralType())
1605 dictStream <<
" R__b.WriteArray((Int_t*)" << field_iter->getName().str() <<
", "
1606 <<
s <<
");" << std::endl;
1607 else if (isFloat16) {
1609 <<
"*)" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1610 }
else if (isDouble32) {
1612 <<
"*)" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1615 <<
"*)" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1618 if (underling_type->isEnumeralType())
1619 dictStream <<
" R__b.WriteArray((Int_t*)" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1620 else if (isFloat16) {
1621 dictStream <<
" R__b.WriteArrayFloat16(" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1622 }
else if (isDouble32) {
1623 dictStream <<
" R__b.WriteArrayDouble32(" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1625 dictStream <<
" R__b.WriteArray(" << field_iter->getName().str() <<
", " <<
s <<
");" << std::endl;
1629 }
else if (underling_type->isEnumeralType()) {
1631 dictStream <<
" void *ptr_" << field_iter->getName().str() <<
" = (void*)&" << field_iter->getName().str() <<
";\n";
1632 dictStream <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_" << field_iter->getName().str() <<
");" << std::endl;
1634 dictStream <<
" R__b << (Int_t)" << field_iter->getName().str() <<
";" << std::endl;
1639 <<
"=Float16_t(R_Dummy);}" << std::endl;
1642 }
else if (isDouble32) {
1645 <<
"=Double32_t(R_Dummy);}" << std::endl;
1667 if (
type.getTypePtr()->isConstantArrayType() &&
1668 type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
1669 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
1673 dictStream <<
" int R__i;" << std::endl;
1676 dictStream <<
" for (R__i = 0; R__i < " <<
s <<
"; R__i++)" << std::endl;
1681 dictStream <<
" R__b << (TObject*)" << field_iter->getName().str();
1686 dictStream <<
"[R__i];" << std::endl;
1687 }
else if (
type.getTypePtr()->isPointerType()) {
1695 ROOT::TMetaUtils::Error(0,
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
1696 dictStream <<
" //R__b.ReadArray(" << field_iter->getName().str() <<
");" << std::endl;
1698 dictStream <<
" //R__b.WriteArray(" << field_iter->getName().str() <<
", __COUNTER__);";
1702 dictStream <<
" " << field_iter->getName().str() <<
"->Streamer(R__b);" << std::endl;
1716 dictStream <<
" R__b << (TObject*)" << field_iter->getName().str() <<
";" << std::endl;
1722 }
else if (
const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
1726 dictStream <<
" int R__i;" << std::endl;
1729 dictStream <<
" for (R__i = 0; R__i < " <<
s <<
"; R__i++)" << std::endl;
1730 std::string mTypeNameStr;
1732 const char *mTypeName = mTypeNameStr.c_str();
1733 const char *constwd =
"const ";
1734 if (strncmp(constwd, mTypeName, strlen(constwd)) == 0) {
1735 mTypeName += strlen(constwd);
1736 dictStream <<
" const_cast< " << mTypeName <<
" &>(" << field_iter->getName().str();
1738 dictStream <<
"[R__i]).Streamer(R__b);" << std::endl;
1742 dictStream <<
"[R__i].Streamer(R__b);" << std::endl;
1748 dictStream <<
" R__b.StreamObject(&(" << field_iter->getName().str() <<
"),typeid("
1749 << field_iter->getName().str() <<
"));" << std::endl;
1760 dictStream <<
" R__b.SetByteCount(R__c, kTRUE);" << std::endl
1761 <<
" }" << std::endl
1762 <<
"}" << std::endl << std::endl;
1764 while (enclSpaceNesting) {
1765 dictStream <<
"} // namespace " << nsname.c_str() << std::endl;
1773 const cling::Interpreter &interp,
1775 std::ostream &dictStream)
1779 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1780 if (clxx == 0)
return;
1785 for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
1797 int enclSpaceNesting = 0;
1803 dictStream <<
"//_______________________________________"
1804 <<
"_______________________________________" << std::endl;
1805 if (add_template_keyword) dictStream <<
"template <> ";
1806 dictStream <<
"void " << clsname <<
"::Streamer(TBuffer &R__b)" << std::endl
1808 <<
" // Stream an object of class " << fullname <<
"." << std::endl << std::endl
1809 <<
" if (R__b.IsReading()) {" << std::endl
1810 <<
" R__b.ReadClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1811 <<
" } else {" << std::endl
1812 <<
" R__b.WriteClassBuffer(" << fullname <<
"::Class(),this);" << std::endl
1813 <<
" }" << std::endl
1814 <<
"}" << std::endl << std::endl;
1816 while (enclSpaceNesting) {
1817 dictStream <<
"} // namespace " << nsname << std::endl;
1825 const cling::Interpreter &interp,
1827 std::ostream &dictStream,
1828 bool isAutoStreamer)
1830 if (isAutoStreamer) {
1840 std::string &code_for_parser)
1842 code_for_parser +=
"#ifdef __CINT__\n\n";
1843 code_for_parser +=
"#pragma link off all globals;\n";
1844 code_for_parser +=
"#pragma link off all classes;\n";
1845 code_for_parser +=
"#pragma link off all functions;\n\n";
1847 for (std::string& arg : InputFiles) {
1849 int nostr = 0, noinp = 0, bcnt = 0,
l = arg.length() - 1;
1850 for (
int j = 0; j < 3; j++) {
1851 if (arg[
l] ==
'-') {
1856 if (arg[
l] ==
'!') {
1861 if (arg[
l] ==
'+') {
1867 if (nostr || noinp) {
1869 if (nostr) strlcat(trail,
"-", 3);
1870 if (noinp) strlcat(trail,
"!", 3);
1873 strlcpy(trail,
"+", 3);
1877 llvm::SmallString<256> filestem = llvm::sys::path::filename(arg);
1878 llvm::sys::path::replace_extension(filestem,
"");
1880 code_for_parser +=
"#pragma link C++ class ";
1881 code_for_parser += filestem.str().str();
1882 if (nostr || noinp || bcnt)
1883 code_for_parser += trail;
1884 code_for_parser +=
";\n";
1887 code_for_parser +=
"\n#endif\n";
1895bool Which(cling::Interpreter &interp,
const char *fname,
string &pname)
1900 static const char *fopenopts =
"rb";
1902 static const char *fopenopts =
"r";
1906 fp = fopen(pname.c_str(), fopenopts);
1912 llvm::SmallVector<std::string, 10> includePaths;
1914 interp.GetIncludePaths(includePaths,
false,
false);
1916 const size_t nPaths = includePaths.size();
1917 for (
size_t i = 0; i < nPaths; i += 1 ) {
1921 fp = fopen(pname.c_str(), fopenopts);
1943 const char *inc = strstr(original,
"\\inc\\");
1945 inc = strstr(original,
"/inc/");
1946 if (inc && strlen(inc) > 5)
1966 cling::Interpreter &interp,
1969 std::ostringstream out;
1977 if (interp.declare(out.str()) != cling::Interpreter::kSuccess) {
1978 const std::string &hdrName
1993static bool WriteAST(StringRef fileName, clang::CompilerInstance *compilerInstance, StringRef iSysRoot,
1994 clang::Module *
module =
nullptr)
1997 llvm::SmallVector<char, 128> buffer;
1998 llvm::BitstreamWriter stream(buffer);
1999 clang::ASTWriter
writer(stream, buffer, compilerInstance->getPCMCache(), {});
2000 std::unique_ptr<llvm::raw_ostream> out =
2001 compilerInstance->createOutputFile(fileName,
true,
2010 compilerInstance->getFrontendOpts().RelocatablePCH =
true;
2012 writer.WriteAST(compilerInstance->getSema(), fileName,
module, iSysRoot);
2015 out->write(&buffer.front(), buffer.size());
2027 const std::string ¤tDirectory)
2029 assert(modGen.
IsPCH() &&
"modGen must be in PCH mode");
2031 std::string iSysRoot(
"/DUMMY_SYSROOT/include/");
2039static bool IncludeHeaders(
const std::vector<std::string> &headers, cling::Interpreter &interpreter)
2042 if (headers.empty())
2046 std::stringstream includes;
2047 for (
const std::string &header : headers) {
2048 includes <<
"#include \"" << header <<
"\"\n";
2050 std::string includeListStr = includes.str();
2051 auto result = interpreter.declare(includeListStr);
2052 return result == cling::Interpreter::CompilationResult::kSuccess;
2060 char platformDefines[64] = {0};
2061#ifdef __INTEL_COMPILER
2062 snprintf(platformDefines, 64,
"-DG__INTEL_COMPILER=%ld", (
long)__INTEL_COMPILER);
2063 clingArgs.push_back(platformDefines);
2066 snprintf(platformDefines, 64,
"-DG__xlC=%ld", (
long)__xlC__);
2067 clingArgs.push_back(platformDefines);
2070 snprintf(platformDefines, 64,
"-DG__GNUC=%ld", (
long)__GNUC__);
2071 snprintf(platformDefines, 64,
"-DG__GNUC_VER=%ld", (
long)__GNUC__ * 1000 + __GNUC_MINOR__);
2072 clingArgs.push_back(platformDefines);
2074#ifdef __GNUC_MINOR__
2075 snprintf(platformDefines, 64,
"-DG__GNUC_MINOR=%ld", (
long)__GNUC_MINOR__);
2076 clingArgs.push_back(platformDefines);
2079 snprintf(platformDefines, 64,
"-DG__HP_aCC=%ld", (
long)__HP_aCC);
2080 clingArgs.push_back(platformDefines);
2083 snprintf(platformDefines, 64,
"-DG__sun=%ld", (
long)__sun);
2084 clingArgs.push_back(platformDefines);
2087 snprintf(platformDefines, 64,
"-DG__SUNPRO_CC=%ld", (
long)__SUNPRO_CC);
2088 clingArgs.push_back(platformDefines);
2090#ifdef _STLPORT_VERSION
2092 snprintf(platformDefines, 64,
"-DG__STLPORT_VERSION=%ld", (
long)_STLPORT_VERSION);
2093 clingArgs.push_back(platformDefines);
2096 snprintf(platformDefines, 64,
"-DG__ia64=%ld", (
long)__ia64__);
2097 clingArgs.push_back(platformDefines);
2100 snprintf(platformDefines, 64,
"-DG__x86_64=%ld", (
long)__x86_64__);
2101 clingArgs.push_back(platformDefines);
2104 snprintf(platformDefines, 64,
"-DG__i386=%ld", (
long)__i386__);
2105 clingArgs.push_back(platformDefines);
2108 snprintf(platformDefines, 64,
"-DG__arm=%ld", (
long)__arm__);
2109 clingArgs.push_back(platformDefines);
2112 snprintf(platformDefines, 64,
"-DG__WIN32=%ld", (
long)_WIN32);
2113 clingArgs.push_back(platformDefines);
2116 snprintf(platformDefines, 64,
"-DG__WIN32=%ld", (
long)WIN32);
2117 clingArgs.push_back(platformDefines);
2121 snprintf(platformDefines, 64,
"-DG__MSC_VER=%ld", (
long)_MSC_VER);
2122 clingArgs.push_back(platformDefines);
2123 snprintf(platformDefines, 64,
"-DG__VISUAL=%ld", (
long)_MSC_VER);
2124 clingArgs.push_back(platformDefines);
2133 return llvm::sys::path::filename(path);
2143 if (std::string::npos != pos) {
2144 dirname.assign(path.begin(), path.begin() + pos + 1);
2155 std::string dictLocation;
2157 return !dictLocation.empty();
2163 std::string &rootmapLibName)
2167 if (rootmapFileName.empty()) {
2169 rootmapFileName = rootmapLibName.substr(0, libExtensionPos) +
".rootmap";
2170 size_t libCleanNamePos = rootmapLibName.find_last_of(
gPathSeparator) + 1;
2171 rootmapLibName = rootmapLibName.substr(libCleanNamePos, std::string::npos);
2173 rootmapLibName.c_str(),
2174 rootmapFileName.c_str());
2183 std::string &ctxtName,
2184 const cling::Interpreter &interpreter,
2185 bool treatParent =
true)
2187 const clang::DeclContext *outerCtxt = treatParent ? theContext.getParent() : &theContext;
2189 if (!outerCtxt)
return;
2191 if (
const clang::RecordDecl *thisRcdDecl = llvm::dyn_cast<clang::RecordDecl>(outerCtxt)) {
2201 std::string &ctxtName,
2202 const cling::Interpreter &interpreter)
2204 const clang::DeclContext *theContext = theDecl.getDeclContext();
2212 const cling::Interpreter &interp)
2214 if (!decls.empty()) {
2215 std::string autoLoadKey;
2216 for (
auto &
d : decls) {
2220 if (autoLoadKey.empty()) {
2221 names.push_back(
d->getQualifiedNameAsString());
2239 const std::string &rootmapLibName,
2240 const std::list<std::string> &classesDefsList,
2241 const std::list<std::string> &classesNames,
2242 const std::list<std::string> &nsNames,
2243 const std::list<std::string> &tdNames,
2244 const std::list<std::string> &enNames,
2245 const std::list<std::string> &varNames,
2247 const std::unordered_set<std::string> headersToIgnore)
2250 std::ofstream rootmapFile(rootmapFileName.c_str());
2258 std::unordered_set<std::string> classesKeys;
2262 if (!classesNames.empty() || !nsNames.empty() || !tdNames.empty() ||
2263 !enNames.empty() || !varNames.empty()) {
2266 if (!classesDefsList.empty()) {
2267 rootmapFile <<
"{ decls }\n";
2268 for (
auto & classDef : classesDefsList) {
2269 rootmapFile << classDef << std::endl;
2271 rootmapFile <<
"\n";
2273 rootmapFile <<
"[ " << rootmapLibName <<
" ]\n";
2276 if (!classesNames.empty()) {
2277 rootmapFile <<
"# List of selected classes\n";
2278 for (
auto & className : classesNames) {
2279 rootmapFile <<
"class " << className << std::endl;
2280 classesKeys.insert(className);
2283 std::unordered_set<std::string> treatedHeaders;
2284 for (
auto & className : classesNames) {
2286 if (className.find(
"<") != std::string::npos)
continue;
2287 if (headersClassesMap.count(className)) {
2288 auto &headers = headersClassesMap.at(className);
2289 if (!headers.empty()){
2290 auto &header = headers.front();
2291 if (treatedHeaders.insert(header).second &&
2292 headersToIgnore.find(header) == headersToIgnore.end() &&
2294 rootmapFile <<
"header " << header << std::endl;
2302 if (!nsNames.empty()) {
2303 rootmapFile <<
"# List of selected namespaces\n";
2304 for (
auto & nsName : nsNames) {
2305 rootmapFile <<
"namespace " << nsName << std::endl;
2310 if (!tdNames.empty()) {
2311 rootmapFile <<
"# List of selected typedefs and outer classes\n";
2312 for (
const auto & autoloadKey : tdNames)
2313 if (classesKeys.insert(autoloadKey).second)
2314 rootmapFile <<
"typedef " << autoloadKey << std::endl;
2319 if (!enNames.empty()){
2320 rootmapFile <<
"# List of selected enums and outer classes\n";
2321 for (
const auto & autoloadKey : enNames)
2322 if (classesKeys.insert(autoloadKey).second)
2323 rootmapFile <<
"enum " << autoloadKey << std::endl;
2327 if (!varNames.empty()){
2328 rootmapFile <<
"# List of selected vars\n";
2329 for (
const auto & autoloadKey : varNames)
2330 if (classesKeys.insert(autoloadKey).second)
2331 rootmapFile <<
"var " << autoloadKey << std::endl;
2345 auto nsPattern =
'{';
auto nsPatternLength = 1;
2346 auto foundNsPos =
line.find_last_of(nsPattern);
2347 if (foundNsPos == std::string::npos)
return {
"",
""};
2348 foundNsPos+=nsPatternLength;
2349 auto extNs =
line.substr(0,foundNsPos);
2351 auto nsEndPattern =
'}';
2352 auto foundEndNsPos =
line.find(nsEndPattern);
2353 auto contained =
line.substr(foundNsPos, foundEndNsPos-foundNsPos);
2355 return {extNs, contained};
2371 std::map<std::string, std::string> nsEntitiesMap;
2372 std::list<std::string> optFwdDeclList;
2373 for (
auto const & fwdDecl : fwdDeclarationsList){
2376 if (extNsAndEntities.first.empty()) {
2378 optFwdDeclList.push_front(fwdDecl);
2380 auto currentVal = nsEntitiesMap[extNsAndEntities.first];
2381 nsEntitiesMap[extNsAndEntities.first] = currentVal +=extNsAndEntities.second;
2385 std::string optFwdDecl;
2386 for (
auto const & extNsAndEntities : nsEntitiesMap) {
2387 optFwdDecl = extNsAndEntities.first;
2388 optFwdDecl += extNsAndEntities.second;
2389 for (
int i = 0; i < std::count(optFwdDecl.begin(), optFwdDecl.end(),
'{'); ++i ){
2392 optFwdDeclList.push_front(optFwdDecl);
2395 return optFwdDeclList;
2403 std::list<std::string> &el_list,
2404 std::unordered_set<std::string> &el_set)
2406 std::stringstream elStream(el);
2409 while (getline(elStream, tmp,
'\n')) {
2411 if (el_set.insert(tmp).second && !tmp.empty()) {
2412 el_list.push_back(tmp);
2423 std::list<std::string> &classesList,
2424 std::list<std::string> &classesListForRootmap,
2425 std::list<std::string> &fwdDeclarationsList,
2426 const cling::Interpreter &interpreter)
2434 std::unordered_set<std::string> classesSet;
2435 std::unordered_set<std::string> outerMostClassesSet;
2437 std::string attrName, attrValue;
2438 bool isClassSelected;
2439 std::unordered_set<std::string> availableFwdDecls;
2440 std::string fwdDeclaration;
2442 fwdDeclaration =
"";
2448 fwdDeclaration =
"";
2455 isClassSelected =
true;
2456 const clang::RecordDecl *rDecl = selClass.GetRecordDecl();
2457 std::string normalizedName;
2458 normalizedName = selClass.GetNormalizedName();
2459 if (!normalizedName.empty() &&
2460 !classesSet.insert(normalizedName).second &&
2461 outerMostClassesSet.count(normalizedName) == 0) {
2462 std::cerr <<
"FATAL: A class with normalized name " << normalizedName
2463 <<
" was already selected. This means that two different instances of"
2464 <<
" clang::RecordDecl had the same name, which is not possible."
2465 <<
" This can be a hint of a serious problem in the class selection."
2466 <<
" In addition, the generated dictionary would not even compile.\n";
2469 classesList.push_back(normalizedName);
2472 const char *reqName(selClass.GetRequestedName());
2475 fwdDeclaration =
"";
2480 if (llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl)) {
2481 fwdDeclaration =
"";
2488 for (
auto ait = rDecl->attr_begin(); ait != rDecl->attr_end(); ++ait) {
2490 attrName ==
"rootmap" &&
2491 attrValue ==
"false") {
2492 attrName = attrValue =
"";
2493 isClassSelected =
false;
2497 if (isClassSelected) {
2513 std::string outerMostClassName;
2515 if (!outerMostClassName.empty() &&
2516 !llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl) &&
2517 classesSet.insert(outerMostClassName).second &&
2518 outerMostClassesSet.insert(outerMostClassName).second) {
2519 classesListForRootmap.push_back(outerMostClassName);
2521 classesListForRootmap.push_back(normalizedName);
2522 if (reqName !=
nullptr && 0 != strcmp(reqName,
"") && reqName != normalizedName) {
2523 classesListForRootmap.push_back(reqName);
2528 std::string demangledName = selClass.GetDemangledTypeInfo();
2529 if (!demangledName.empty()) {
2534 if (demangledName != normalizedName && (!reqName || demangledName != reqName)) {
2536 classesListForRootmap.push_back(demangledName);
2542 classesListForRootmap.sort();
2555 for (RScanner::NamespaceColl_t::const_iterator selNsIter = scan.
fSelectedNamespaces.begin();
2570 if (clang::CXXRecordDecl *CXXRD =
2571 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
2583 if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
2586 const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2589 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
2605 if (interp.parseForModule(
"#include \"TStreamerInfo.h\"\n"
2606 "#include \"TFile.h\"\n"
2607 "#include \"TObjArray.h\"\n"
2608 "#include \"TVirtualArray.h\"\n"
2609 "#include \"TStreamerElement.h\"\n"
2610 "#include \"TProtoClass.h\"\n"
2611 "#include \"TBaseClass.h\"\n"
2612 "#include \"TListOfDataMembers.h\"\n"
2613 "#include \"TListOfEnums.h\"\n"
2614 "#include \"TListOfEnumsWithLock.h\"\n"
2615 "#include \"TDataMember.h\"\n"
2616 "#include \"TEnum.h\"\n"
2617 "#include \"TEnumConstant.h\"\n"
2618 "#include \"TDictAttributeMap.h\"\n"
2619 "#include \"TMessageHandler.h\"\n"
2620 "#include \"TArray.h\"\n"
2621 "#include \"TRefArray.h\"\n"
2622 "#include \"root_std_complex.h\"\n")
2623 != cling::Interpreter::kSuccess)
2634 cling::Interpreter &interp,
2639 bool writeEmptyRootPCM)
2643 bool needsCollectionProxy =
false;
2665 auto nsName =
ns.GetNamespaceDecl()->getQualifiedNameAsString();
2666 if (nsName.find(
"(anonymous)") == std::string::npos)
2671 if (!selClass.GetRecordDecl()->isCompleteDefinition()) {
2675 if (selClass.RequestOnlyTClass()) {
2683 if (clang::CXXRecordDecl *CXXRD =
2684 llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
2688 const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2699 needsCollectionProxy);
2714 if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
2718 const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2730 if (!selClass.GetRecordDecl()->isCompleteDefinition() || !selClass.RequestOnlyTClass()) {
2734 const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
2739 needsCollectionProxy);
2768 if (finRetCode != 0)
return finRetCode;
2778 dictStream <<
"// Do NOT change. Changes will be lost next time file is generated\n\n"
2779 <<
"#define R__DICTIONARY_FILENAME " << main_dictname << std::endl
2782 <<
"#define R__NO_DEPRECATION" << std::endl
2787 <<
"\n/*******************************************************************/\n"
2788 <<
"#include <stddef.h>\n"
2789 <<
"#include <stdio.h>\n"
2790 <<
"#include <stdlib.h>\n"
2791 <<
"#include <string.h>\n"
2792 <<
"#include <assert.h>\n"
2793 <<
"#define G__DICTIONARY\n"
2794 <<
"#include \"RConfig.h\"\n"
2795 <<
"#include \"TClass.h\"\n"
2796 <<
"#include \"TDictAttributeMap.h\"\n"
2797 <<
"#include \"TInterpreter.h\"\n"
2798 <<
"#include \"TROOT.h\"\n"
2799 <<
"#include \"TBuffer.h\"\n"
2800 <<
"#include \"TMemberInspector.h\"\n"
2801 <<
"#include \"TInterpreter.h\"\n"
2802 <<
"#include \"TVirtualMutex.h\"\n"
2803 <<
"#include \"TError.h\"\n\n"
2804 <<
"#ifndef G__ROOT\n"
2805 <<
"#define G__ROOT\n"
2807 <<
"#include \"RtypesImp.h\"\n"
2808 <<
"#include \"TIsAProxy.h\"\n"
2809 <<
"#include \"TFileMergeInfo.h\"\n"
2810 <<
"#include <algorithm>\n"
2811 <<
"#include \"TCollectionProxyInfo.h\"\n"
2812 <<
"/*******************************************************************/\n\n"
2813 <<
"#include \"TDataMember.h\"\n\n";
2820 dictStream <<
"// The generated code does not explicitly qualifies STL entities\n"
2821 <<
"namespace std {} using namespace std;\n\n";
2827 const std::string &includeForSource,
2828 const std::string &extraIncludes)
2830 dictStream <<
"// Header files passed as explicit arguments\n"
2831 << includeForSource << std::endl
2832 <<
"// Header files passed via #pragma extra_include\n"
2833 << extraIncludes << std::endl;
2839#if defined(R__IOSSIM) || defined(R__IOS)
2858class tempFileNamesCatalog {
2861 tempFileNamesCatalog(): m_size(0), m_emptyString(
"") {};
2863 std::string getTmpFileName(
const std::string &filename) {
2864 return filename +
"_tmp_" + std::to_string(getpid());
2870 void addFileName(std::string &nameStr) {
2871 if (nameStr.empty())
return;
2873 std::string tmpNameStr(getTmpFileName(nameStr));
2876 const char *
name(nameStr.c_str());
2877 const char *tmpName(tmpNameStr.c_str());
2879 m_names.push_back(nameStr);
2880 m_tempNames.push_back(tmpNameStr);
2884 if (0 == std::rename(
name , tmpName)) {
2889 nameStr = tmpNameStr;
2900 for (
unsigned int i = 0; i < m_size; ++i) {
2901 const char *tmpName = m_tempNames[i].c_str();
2903 std::ifstream ifile(tmpName);
2907 if (0 != std::remove(tmpName)) {
2920 for (
unsigned int i = 0; i < m_size; ++i) {
2921 const char *tmpName = m_tempNames[i].c_str();
2922 const char *
name = m_names[i].c_str();
2924 std::ifstream ifile(tmpName);
2931 if (ifile.is_open())
2933 if (0 != std::rename(tmpName ,
name)) {
2934 if (llvm::sys::fs::copy_file(tmpName ,
name)) {
2935 llvm::sys::fs::remove(tmpName);
2939 if (0 != std::rename(tmpName ,
name)) {
2950 const std::string &getFileName(
const std::string &tmpFileName) {
2951 size_t i = std::distance(m_tempNames.begin(),
2952 find(m_tempNames.begin(), m_tempNames.end(), tmpFileName));
2953 if (i == m_tempNames.size())
return m_emptyString;
2960 std::cout <<
"Restoring files in temporary file catalog:\n";
2961 for (
unsigned int i = 0; i < m_size; ++i) {
2962 std::cout << m_tempNames[i] <<
" --> " << m_names[i] << std::endl;
2967 unsigned int m_size;
2968 const std::string m_emptyString;
2969 std::vector<std::string> m_names;
2970 std::vector<std::string> m_tempNames;
2977 tempFileNamesCatalog &tmpCatalog)
2979 std::string splitDictName(tmpCatalog.getFileName(dictpathname));
2980 const size_t dotPos = splitDictName.find_last_of(
".");
2981 splitDictName.insert(dotPos,
"_classdef");
2982 tmpCatalog.addFileName(splitDictName);
2983 return new std::ofstream(splitDictName.c_str());
2992 std::list<std::string> &diagnosticPragmas)
2994 static const std::string
pattern(
"-Wno-");
2998 if (arg ==
"-Wno-noexcept-type") {
3005 diagnosticPragmas.push_back(arg);
3011 cling::Interpreter &interp)
3014 std::string fwdDecl;
3015 std::string initStr(
"{");
3017 for (
auto & strigNargsToKeepPair : fwdDeclnArgsToSkipColl) {
3018 auto &clTemplDecl = *strigNargsToKeepPair.first;
3022 + std::to_string(strigNargsToKeepPair.second)
3025 if (!fwdDeclnArgsToSkipColl.empty())
3036 if (qt.isNull())
return qt;
3037 clang::QualType thisQt(qt);
3038 while (thisQt->isPointerType() ||
3039 thisQt->isReferenceType()) {
3040 thisQt = thisQt->getPointeeType();
3050 const cling::Interpreter &interp,
3051 std::set<const clang::CXXRecordDecl *> &visitedDecls)
3053 std::list<std::string> headers;
3056 cling::Interpreter::PushTransactionRAII RAII(&interp);
3059 if (!visitedDecls.insert(rcd.getCanonicalDecl()).second)
3063 if (
const clang::ClassTemplateSpecializationDecl *tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd)) {
3066 for (
auto & tArg : tsd->getTemplateArgs().asArray()) {
3069 if (tArgQualType.isNull())
continue;
3070 if (
const clang::CXXRecordDecl *tArgCxxRcd = tArgQualType->getAsCXXRecordDecl()) {
3071 headers.splice(headers.end(),
RecordDecl2Headers(*tArgCxxRcd, interp, visitedDecls));
3078 for (
auto baseIt = tsd->bases_begin(); baseIt != tsd->bases_end(); baseIt++) {
3080 if (baseQualType.isNull())
continue;
3081 if (
const clang::CXXRecordDecl *baseRcdPtr = baseQualType->getAsCXXRecordDecl()) {
3082 headers.splice(headers.end(),
RecordDecl2Headers(*baseRcdPtr, interp, visitedDecls));
3087 for (
auto declIt = tsd->decls_begin(); declIt != tsd->decls_end(); ++declIt) {
3088 if (
const clang::FieldDecl *fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*declIt)) {
3090 if (fieldQualType.isNull()) continue ;
3091 if (
const clang::CXXRecordDecl *fieldCxxRcd = fieldQualType->getAsCXXRecordDecl()) {
3092 if (fieldCxxRcd->hasDefinition())
3093 headers.splice(headers.end(),
RecordDecl2Headers(*fieldCxxRcd, interp, visitedDecls));
3099 for (
auto methodIt = tsd->method_begin(); methodIt != tsd->method_end(); ++methodIt) {
3101 for (
auto & fPar : methodIt->parameters()) {
3103 if (fParQualType.isNull())
continue;
3104 if (
const clang::CXXRecordDecl *fParCxxRcd = fParQualType->getAsCXXRecordDecl()) {
3105 if (fParCxxRcd->hasDefinition())
3106 headers.splice(headers.end(),
RecordDecl2Headers(*fParCxxRcd, interp, visitedDecls));
3111 if (retQualType.isNull())
continue;
3112 if (
const clang::CXXRecordDecl *retCxxRcd = retQualType->getAsCXXRecordDecl()) {
3113 if (retCxxRcd->hasDefinition())
3122 headers.emplace_back(header);
3135 if (
auto dclCtxt= rcd.getDeclContext()){
3136 if (! dclCtxt->isStdNamespace()){
3145 auto clAsTmplSpecDecl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd);
3146 if (!clAsTmplSpecDecl)
return false;
3151 auto& astCtxt = rcd.getASTContext();
3152 auto& templInstArgs = clAsTmplSpecDecl->getTemplateInstantiationArgs();
3153 for (
auto&& arg : templInstArgs.asArray()){
3155 auto argKind = arg.getKind();
3157 if (argKind == clang::TemplateArgument::Integral)
continue;
3161 auto argQualType = arg.getAsType();
3162 auto isPOD = argQualType.isPODType(astCtxt);
3164 if (isPOD)
continue;
3166 auto argType = argQualType.getTypePtr();
3167 if (
auto recType = llvm::dyn_cast<clang::RecordType>(argType)){
3170 if (isArgGoodForAutoParseMap)
continue;
3189 const cling::Interpreter &interp)
3191 std::set<const clang::CXXRecordDecl *> visitedDecls;
3192 std::unordered_set<std::string> buffer;
3193 std::string autoParseKey;
3196 for (
auto & annotatedRcd : annotatedRcds) {
3197 if (
const clang::CXXRecordDecl *cxxRcd =
3198 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(annotatedRcd.GetRecordDecl())) {
3200 visitedDecls.clear();
3204 headers.remove_if([&buffer](
const std::string &
s) {
3205 return !buffer.insert(
s).
second;
3208 if (autoParseKey.empty()) autoParseKey = annotatedRcd.GetNormalizedName();
3210 headersDeclsMap[autoParseKey] = headers;
3211 headersDeclsMap[annotatedRcd.GetRequestedName()] = headers;
3213 ROOT::TMetaUtils::Info(0,
"Class %s is not included in the set of autoparse keys.\n", autoParseKey.c_str());
3218 if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(cxxRcd)){
3219 headersClassesMap[autoParseKey] = headersDeclsMap[autoParseKey];
3220 headersClassesMap[annotatedRcd.GetRequestedName()] = headersDeclsMap[annotatedRcd.GetRequestedName()];
3226 for (
auto & tDef : tDefDecls) {
3227 if (clang::CXXRecordDecl *cxxRcd = tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
3229 visitedDecls.clear();
3234 headers.remove_if([&buffer](
const std::string &
s) {
3235 return !buffer.insert(
s).
second;
3238 if (autoParseKey.empty()) autoParseKey = tDef->getQualifiedNameAsString();
3239 headersDeclsMap[autoParseKey] = headers;
3244 for (
auto & func : funcDecls) {
3250 for (
auto & var : varDecls) {
3256 for (
auto & en : enumDecls) {
3266 const cling::Interpreter &interp)
3268 std::string newFwdDeclString;
3272 std::string fwdDeclString;
3274 std::unordered_set<std::string> fwdDecls;
3295 std::vector<const clang::Decl *> selectedDecls(scan.
fSelectedClasses.size());
3300 selectedDecls.begin(),
3304 selectedDecls.push_back(TD);
3328 if (fwdDeclString.empty()) fwdDeclString =
"";
3329 return fwdDeclString;
3336 const std::string &detectedUmbrella,
3337 bool payLoadOnly =
false)
3339 std::string headerName;
3342 std::cout <<
"Class-headers Mapping:\n";
3343 std::string headersClassesMapString =
"";
3344 for (
auto const & classHeaders : headersClassesMap) {
3346 std::cout <<
" o " << classHeaders.first <<
" --> ";
3347 headersClassesMapString +=
"\"";
3348 headersClassesMapString += classHeaders.first +
"\"";
3349 for (
auto const & header : classHeaders.second) {
3350 headerName = (detectedUmbrella == header || payLoadOnly) ?
"payloadCode" :
"\"" + header +
"\"";
3351 headersClassesMapString +=
", " + headerName;
3353 std::cout <<
", " << headerName;
3358 std::cout << std::endl;
3359 headersClassesMapString +=
", \"@\",\n";
3361 headersClassesMapString +=
"nullptr";
3362 return headersClassesMapString;
3385 static const std::vector<std::string> namePrfxes {
3388 auto pos = find_if(namePrfxes.begin(),
3390 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3391 return namePrfxes.end() == pos;
3398 static const std::vector<std::string> uclNamePrfxes {
3402 static const std::set<std::string> unsupportedClassesNormNames{
3405 if ( unsupportedClassesNormNames.count(
name) == 1)
return false;
3406 auto pos = find_if(uclNamePrfxes.begin(),
3407 uclNamePrfxes.end(),
3408 [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
3409 return uclNamePrfxes.end() == pos;
3419 for (
auto&& aRcd : annotatedRcds){
3420 auto clName = aRcd.GetNormalizedName();
3422 std::cerr <<
"Error: Class " << clName <<
" has been selected but "
3423 <<
"currently the support for its I/O is not yet available. Note that "
3424 << clName <<
", even if not selected, will be available for "
3425 <<
"interpreted code.\n";
3429 std::cerr <<
"Error: It is not necessary to explicitly select class "
3430 << clName <<
". I/O is supported for it transparently.\n";
3439class TRootClingCallbacks :
public cling::InterpreterCallbacks {
3441 std::list<std::string>& fFilesIncludedByLinkdef;
3442 bool isLocked =
false;
3444 TRootClingCallbacks(cling::Interpreter* interp, std::list<std::string>& filesIncludedByLinkdef):
3445 InterpreterCallbacks(interp),
3446 fFilesIncludedByLinkdef(filesIncludedByLinkdef){};
3448 ~TRootClingCallbacks(){};
3450 virtual void InclusionDirective(clang::SourceLocation ,
const clang::Token & ,
3451 llvm::StringRef FileName,
bool IsAngled, clang::CharSourceRange ,
3452 const clang::FileEntry * , llvm::StringRef ,
3453 llvm::StringRef ,
const clang::Module * )
3455 if (isLocked)
return;
3456 if (IsAngled)
return;
3457 auto& PP = m_Interpreter->getCI()->getPreprocessor();
3458 auto curLexer = PP.getCurrentFileLexer();
3459 if (!curLexer)
return;
3460 auto fileEntry = curLexer->getFileEntry();
3461 if (!fileEntry)
return;
3462 auto thisFileName = fileEntry->getName();
3463 auto fileNameAsString = FileName.str();
3465 if (isThisLinkdef) {
3467 if (isTheIncludedLinkdef) {
3468 fFilesIncludedByLinkdef.clear();
3471 fFilesIncludedByLinkdef.emplace_back(fileNameAsString.c_str());
3484 virtual void EnteredSubmodule(clang::Module* M,
3485 clang::SourceLocation ImportLoc,
3488 using namespace clang;
3489 if (llvm::StringRef(M->Name).endswith(
"ACLiC_dict")) {
3490 Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
3491 HeaderSearch& HS = PP.getHeaderSearchInfo();
3493 Module* CoreModule = HS.lookupModule(
"Core",
false);
3494 assert(M &&
"Must have module Core");
3495 PP.makeModuleVisible(CoreModule, ImportLoc);
3510class CheckModuleBuildClient :
public clang::DiagnosticConsumer {
3511 clang::DiagnosticConsumer *fChild;
3513 clang::ModuleMap &fMap;
3516 CheckModuleBuildClient(clang::DiagnosticConsumer *Child,
bool OwnsChild, clang::ModuleMap &
Map)
3517 : fChild(Child), fOwnsChild(OwnsChild), fMap(
Map)
3521 ~CheckModuleBuildClient()
3527 virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &
Info)
override
3529 using namespace clang::diag;
3535 std::string moduleName;
3536 const clang::Module *
module =
nullptr;
3539 const auto &ID =
Info.getID();
3540 if (ID == remark_module_build || ID == remark_module_build_done) {
3541 moduleName =
Info.getArgStdStr(0);
3542 module = fMap.findModule(moduleName);
3548 "Couldn't find module %s in the available modulemaps. This"
3549 "prevents us from correctly diagnosing wrongly built modules.\n",
3550 moduleName.c_str());
3557 bool isROOTSystemModuleDiag =
module && llvm::StringRef(moduleName).startswith(
"ROOT_");
3559 if (!isROOTSystemModuleDiag && !isSystemModuleDiag)
3560 fChild->HandleDiagnostic(DiagLevel,
Info);
3562 if (ID == remark_module_build && !isROOTSystemModuleDiag && !isSystemModuleDiag) {
3564 "Had to build non-system module %s implicitly. You first need to\n"
3565 "generate the dictionary for %s or mark the C++ module as a system\n"
3566 "module if you provided your own system modulemap file:\n"
3567 "%s [system] { ... }\n",
3568 moduleName.c_str(), moduleName.c_str(), moduleName.c_str());
3573 virtual void clear()
override
3576 DiagnosticConsumer::clear();
3579 virtual void BeginSourceFile(
const clang::LangOptions &LangOpts,
const clang::Preprocessor *PP)
override
3581 fChild->BeginSourceFile(LangOpts, PP);
3582 DiagnosticConsumer::BeginSourceFile(LangOpts, PP);
3585 virtual void EndSourceFile()
override
3587 fChild->EndSourceFile();
3588 DiagnosticConsumer::EndSourceFile();
3591 virtual void finish()
override
3594 DiagnosticConsumer::finish();
3597 virtual bool IncludeInDiagnosticCounts()
const override {
return fChild->IncludeInDiagnosticCounts(); }
3601#if defined(_WIN32) && defined(_MSC_VER)
3605 const char *EnablePopups = getenv(
"Cling_GuiOnAssert");
3606 if (EnablePopups ==
nullptr || EnablePopups[0] ==
'0') {
3607 ::_set_error_mode(_OUT_TO_STDERR);
3608 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3609 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3610 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3611 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
3612 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3613 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3618static llvm::cl::opt<bool>
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
3620static llvm::cl::opt<bool>
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
3631static llvm::cl::opt<VerboseLevel>
3633 llvm::cl::values(clEnumVal(
v,
"Show errors."),
3634 clEnumVal(
v0,
"Show only fatal errors."),
3635 clEnumVal(
v1,
"Show errors (the same as -v)."),
3636 clEnumVal(
v2,
"Show warnings (default)."),
3637 clEnumVal(
v3,
"Show notes."),
3638 clEnumVal(
v4,
"Show information.")),
3642static llvm::cl::opt<bool>
3643gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3646static llvm::cl::opt<bool>
3647gOptReflex(
"reflex", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3650static llvm::cl::opt<bool>
3651gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3654static llvm::cl::opt<std::string>
3656 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
3659static llvm::cl::opt<bool>
3661 llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
3664static llvm::cl::opt<std::string>
3666 llvm::cl::desc(
"<output dictionary file>"),
3668static llvm::cl::opt<bool>
3669gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3671static llvm::cl::opt<bool>
3672gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
3674static llvm::cl::list<std::string>
3676 llvm::cl::desc(
"Generate rootmap file."),
3678static llvm::cl::opt<std::string>
3680 llvm::cl::desc(
"Generate a rootmap file with the specified name."),
3682static llvm::cl::opt<bool>
3684 llvm::cl::desc(
"Generate a C++ module."),
3686static llvm::cl::list<std::string>
3688 llvm::cl::desc(
"Specify a C++ modulemap file."),
3691static llvm::cl::opt<bool>
3693 llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
3695static llvm::cl::opt<bool>
3697 llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
3699static llvm::cl::opt<bool>
3701 llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
3703static llvm::cl::opt<bool>
3705 llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
3707static llvm::cl::opt<bool>
3709 llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\
3710information and another the interactivity support."),
3712static llvm::cl::opt<bool>
3715 llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
3717static llvm::cl::opt<std::string>
3719 llvm::cl::desc(
"The path to the library of the built dictionary."),
3721static llvm::cl::list<std::string>
3723 llvm::cl::desc(
"The list of dependent modules of the dictionary."),
3725static llvm::cl::list<std::string>
3727 llvm::cl::desc(
"Do not store the <path> in the dictionary."),
3731static llvm::cl::opt<bool>
3733 llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
3741static llvm::cl::opt<bool>
3744 llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
3746static llvm::cl::opt<bool>
3748 llvm::cl::desc(
"Check the selection syntax only."),
3750static llvm::cl::opt<bool>
3752 llvm::cl::desc(
"Fail if there are warnings."),
3754static llvm::cl::opt<bool>
3756 llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
3758static llvm::cl::opt<std::string>
3760 llvm::cl::desc(
"Specify an isysroot."),
3763static llvm::cl::list<std::string>
3765 llvm::cl::desc(
"Specify an include path."),
3767static llvm::cl::list<std::string>
3769 llvm::cl::desc(
"Specify defined macros."),
3771static llvm::cl::list<std::string>
3773 llvm::cl::desc(
"Specify undefined macros."),
3775static llvm::cl::list<std::string>
3777 llvm::cl::desc(
"Specify compiler diagnostics options."),
3779static llvm::cl::list<std::string>
3781 llvm::cl::desc(
"<list of dictionary header files> <LinkDef file>"),
3783static llvm::cl::list<std::string>
3785 llvm::cl::desc(
"Consumes all unrecognized options."),
3788static llvm::cl::SubCommand
3791static llvm::cl::list<std::string>
3793 llvm::cl::desc(
"Consumes options and sends them to cling."),
3803 std::vector<std::string> &missingHeaders)
3806 std::vector<clang::Module::Header> moduleHeaders;
3808 [&moduleHeaders](
const clang::Module::Header &
h) { moduleHeaders.push_back(
h); });
3810 bool foundAllHeaders =
true;
3815 for (
const std::string &header : modGen.
GetHeaders()) {
3816 bool headerFound =
false;
3817 for (
const clang::Module::Header &moduleHeader : moduleHeaders) {
3818 if (header == moduleHeader.NameAsWritten) {
3824 missingHeaders.push_back(header);
3825 foundAllHeaders =
false;
3828 return foundAllHeaders;
3834 StringRef LinkdefPath,
const std::string &moduleName)
3836 clang::CompilerInstance *CI = interpreter.getCI();
3837 clang::HeaderSearch &headerSearch = CI->getPreprocessor().getHeaderSearchInfo();
3838 headerSearch.loadTopLevelSystemModules();
3841 clang::Module *
module = headerSearch.lookupModule(StringRef(moduleName));
3846 moduleName.c_str());
3853 std::vector<std::string> missingHeaders;
3856 std::stringstream msgStream;
3857 msgStream <<
"warning: Couldn't find in "
3858 <<
module->PresumedModuleMapFile
3859 <<
" the following specified headers in "
3860 <<
"the module " <<
module->Name <<
":\n";
3861 for (
auto &
H : missingHeaders) {
3862 msgStream <<
" " <<
H <<
"\n";
3864 std::string warningMessage = msgStream.str();
3866 bool maybeUmbrella = modGen.
GetHeaders().size() == 1;
3877 ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
3878 warningMessage.c_str(),
3897 llvm::StringRef moduleName = llvm::sys::path::filename(rdictName);
3898 moduleName.consume_front(
"lib");
3899 moduleName.consume_back(
".pcm");
3900 moduleName.consume_back(
"_rdict");
3908 bool isGenreflex =
false)
3911 auto &opts = llvm::cl::getRegisteredOptions();
3912 auto &optHelp = *opts[
"help"];
3913 llvm::cl::alias optHelpAlias1(
"h",
3914 llvm::cl::desc(
"Alias for -help"),
3915 llvm::cl::aliasopt(optHelp));
3916 llvm::cl::alias optHelpAlias2(
"?",
3917 llvm::cl::desc(
"Alias for -help"),
3918 llvm::cl::aliasopt(optHelp));
3924 const char *executableFileName = argv[0];
3926 llvm::sys::PrintStackTraceOnErrorSignal(executableFileName);
3927 llvm::PrettyStackTraceProgram X(argc, argv);
3930#if defined(R__WIN32) && !defined(R__WINGCC)
3935 for (
int iic = 1 ; iic < argc; ++iic) {
3936 std::string iiarg(argv[iic]);
3938 size_t len = iiarg.length();
3940 char *argviic =
new char[len + 1];
3941 strlcpy(argviic, iiarg.c_str(), len + 1);
3942 argv[iic] = argviic;
3950 llvm::cl::ParseCommandLineOptions(argc, argv,
"rootcling");
3954 std::vector<const char *> clingArgsC;
3955 clingArgsC.push_back(executableFileName);
3957 clingArgsC.push_back(
"-I");
3964 clingArgsC.push_back(Opt.c_str());
3966 auto interp = llvm::make_unique<cling::Interpreter>(clingArgsC.size(),
3968 llvmResourceDir.c_str());
3971 return interp->getDiagnostics().hasFatalErrorOccurred();
3974 std::string dictname;
3988 llvm::cl::PrintHelpMessage();
4003 if ((fp = fopen(filein.c_str(),
"r")) == 0) {
4004 ROOT::TMetaUtils::Error(0,
"%s: The input list file %s does not exist\n", executableFileName, filein.c_str());
4031 ROOT::TMetaUtils::Error(0,
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
4036 std::vector<std::string> clingArgs;
4037 clingArgs.push_back(executableFileName);
4038 clingArgs.push_back(
"-iquote.");
4044 std::list<std::string> diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
4066 ROOT::TMetaUtils::Error(
"",
"Multidict requested but no target library. Please specify one with the -s argument.\n");
4071 clingArgs.push_back(std::string(
"-D") + PPDefine);
4074 clingArgs.push_back(std::string(
"-U") + PPUndefine);
4077 clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(IncludePath));
4079 for (
const std::string &WDiag :
gOptWDiags) {
4080 const std::string FullWDiag = std::string(
"-W") + WDiag;
4084 clingArgs.push_back(FullWDiag);
4088 clingArgs.push_back(std::string(
"-I") + includeDir);
4090 std::vector<std::string> pcmArgs;
4091 for (
size_t parg = 0,
n = clingArgs.size(); parg <
n; ++parg) {
4092 auto thisArg = clingArgs[parg];
4094 if (thisArg ==
"-c" ||
4098 unsigned int offset = 2;
4099 char c = thisArg[offset];
4100 while (
c ==
' ')
c = thisArg[++offset];
4104 [&](
const std::string& path){
4105 return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
4106 if (excludePathsEnd != excludePathPos)
continue;
4108 pcmArgs.push_back(thisArg);
4115 clingArgs.push_back(
"-D__ROOTCLING__");
4118 clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
4119#elif defined(R__WIN32)
4120 clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
4123 clingArgs.push_back(
"-D_XKEYCHECK_H");
4125 clingArgs.push_back(
"-DNOMINMAX");
4127 clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
4130 clingArgs.push_back(
"-fsyntax-only");
4132 clingArgs.push_back(
"-fPIC");
4134 clingArgs.push_back(
"-Xclang");
4135 clingArgs.push_back(
"-fmodules-embed-all-files");
4136 clingArgs.push_back(
"-Xclang");
4137 clingArgs.push_back(
"-main-file-name");
4138 clingArgs.push_back(
"-Xclang");
4139 clingArgs.push_back((dictname +
".h").c_str());
4147 std::string outputFile;
4149 StringRef moduleName;
4154 auto clingArgsInterpreter = clingArgs;
4163 clingArgsInterpreter.push_back(
"-fmodules");
4164 clingArgsInterpreter.push_back(
"-fno-implicit-module-maps");
4167 clingArgsInterpreter.push_back(
"-fmodule-map-file=" + modulemap);
4169 clingArgsInterpreter.push_back(
"-fmodule-map-file=" +
4171 "/module.modulemap");
4173 if (llvm::sys::fs::exists(ModuleMapCWD))
4174 clingArgsInterpreter.push_back(
"-fmodule-map-file=" + ModuleMapCWD);
4181 clingArgsInterpreter.push_back(
"-fmodule-name");
4182 clingArgsInterpreter.push_back(moduleName.str());
4192 if (moduleName ==
"Core") {
4194 remove((moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_intrinsics.pcm").str().c_str());
4195 remove((moduleCachePath + llvm::sys::path::get_separator() +
"_Builtin_stddef_max_align_t.pcm").str().c_str());
4196 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime.pcm").str().c_str());
4197 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Cling_Runtime_Extra.pcm").str().c_str());
4199 remove((moduleCachePath + llvm::sys::path::get_separator() +
"vcruntime.pcm").str().c_str());
4203 remove((moduleCachePath + llvm::sys::path::get_separator() +
"Darwin.pcm").str().c_str());
4205 remove((moduleCachePath + llvm::sys::path::get_separator() +
"libc.pcm").str().c_str());
4207 remove((moduleCachePath + llvm::sys::path::get_separator() +
"std.pcm").str().c_str());
4208 remove((moduleCachePath + llvm::sys::path::get_separator() +
"cuda.pcm").str().c_str());
4209 remove((moduleCachePath + llvm::sys::path::get_separator() +
"boost.pcm").str().c_str());
4210 remove((moduleCachePath + llvm::sys::path::get_separator() +
"tinyxml2.pcm").str().c_str());
4211 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Config.pcm").str().c_str());
4212 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Rtypes.pcm").str().c_str());
4213 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_C.pcm").str().c_str());
4214 remove((moduleCachePath + llvm::sys::path::get_separator() +
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
4219 clingArgsInterpreter.push_back(
"-fmodules-cache-path=" + moduleCachePath);
4223 clingArgsInterpreter.push_back(
"-v");
4226 std::vector<const char *> clingArgsC;
4227 for (
auto const &clingArg : clingArgsInterpreter) {
4229 std::cerr <<
"Argument \""<< clingArg <<
"\" is not a supported cling argument. "
4230 <<
"This could be mistyped rootcling argument. Please check the commandline.\n";
4233 clingArgsC.push_back(clingArg.c_str());
4237 std::unique_ptr<cling::Interpreter> owningInterpPtr;
4238 cling::Interpreter* interpPtr =
nullptr;
4240 std::list<std::string> filesIncludedByLinkdef;
4243 clingArgsC.push_back(
"-resource-dir");
4244 clingArgsC.push_back(llvmResourceDir.c_str());
4245 clingArgsC.push_back(0);
4247 extraArgs = &clingArgsC[1];
4250 std::unique_ptr<TRootClingCallbacks> callBacks (
new TRootClingCallbacks(interpPtr, filesIncludedByLinkdef));
4251 interpPtr->setCallbacks(std::move(callBacks));
4256 clingArgsC.push_back(
"-ffast-math");
4259 owningInterpPtr.reset(
new cling::Interpreter(clingArgsC.size(), &clingArgsC[0],
4260 llvmResourceDir.c_str()));
4261 interpPtr = owningInterpPtr.get();
4268 interpPtr->loadModule(
"_Builtin_intrinsics",
true);
4270 cling::Interpreter &interp = *interpPtr;
4271 clang::CompilerInstance *CI = interp.getCI();
4273 CI->getFrontendOpts().ModulesEmbedAllFiles =
true;
4274 CI->getSourceManager().setAllFilesAreTransient(
true);
4276 clang::Preprocessor &PP = CI->getPreprocessor();
4277 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
4278 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
4279 auto &diags = interp.getDiagnostics();
4286 diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
4290 auto recordingClient =
new CheckModuleBuildClient(diags.getClient(), diags.ownsClient(), moduleMap);
4291 diags.setClient(recordingClient,
true);
4297 interp.DumpIncludePath();
4302 interp.printIncludedFiles(llvm::outs());
4303 llvm::outs() <<
"\n\n";
4304 llvm::outs().flush();
4307 const clang::LangOptions& LangOpts
4308 = interp.getCI()->getASTContext().getLangOpts();
4309#define LANGOPT(Name, Bits, Default, Description) \
4310 ROOT::TMetaUtils::Info(0, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
4311#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4312#include "clang/Basic/LangOptions.def"
4316 interp.getOptions().ErrorOut =
true;
4317 interp.enableRawInput(
true);
4321 if (DepMod.endswith(
"_rdict.pcm")) {
4327 if (!interp.loadModule(DepMod,
false)) {
4334 if (interp.declare(
"namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
4340 if (interp.declare(
"#include <assert.h>\n") != cling::Interpreter::kSuccess
4341 || interp.declare(
"#include \"Rtypes.h\"\n"
4342 "#include \"TObject.h\"") != cling::Interpreter::kSuccess
4351 interp.declare(
"#include <string>");
4353 interp.declare(
"#include <RtypesCore.h>");
4361 clingArgs.push_back(
"-D__CINT__");
4362 clingArgs.push_back(
"-D__MAKECINT__");
4368 std::string interpPragmaSource;
4369 std::string includeForSource;
4370 std::string interpreterDeclarations;
4371 std::string linkdef;
4377 if (isSelectionFile) {
4379 linkdef = optHeaderFileName;
4382 executableFileName, optHeaderFileName.c_str());
4388 std::string fullheader(optHeaderFileName);
4391 if (fullheader[fullheader.length() - 1] ==
'+') {
4392 fullheader.erase(fullheader.length() - 1);
4397 interpPragmaSource += std::string(
"#include \"") + header +
"\"\n";
4398 if (!isSelectionFile) {
4406 includeForSource += std::string(
"#include \"") + fullheader +
"\"\n";
4407 pcmArgs.push_back(header);
4409 interpreterDeclarations += std::string(
"#include \"") + header +
"\"\n";
4414 bool hasSelectionFile = !linkdef.empty();
4415 unsigned expectedHeaderFilesSize = 1 + hasSelectionFile;
4426 if (!newName.empty())
4439 string incCurDir =
"-I";
4440 incCurDir += currentDirectory;
4441 pcmArgs.push_back(incCurDir);
4446 std::stringstream res;
4447 const char* delim=
"\n";
4448 std::copy(diagnosticPragmas.begin(),
4449 diagnosticPragmas.end(),
4450 std::ostream_iterator<std::string>(res, delim));
4451 interp.declare(res.str());
4454 class IgnoringPragmaHandler:
public clang::PragmaNamespace {
4456 IgnoringPragmaHandler(
const char* pragma):
4457 clang::PragmaNamespace(pragma) {}
4458 void HandlePragma(clang::Preprocessor &PP,
4459 clang::PragmaIntroducerKind Introducer,
4460 clang::Token &tok) {
4461 PP.DiscardUntilEndOfDirective();
4467 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"link"));
4468 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"extra_include"));
4469 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"read"));
4470 PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"create"));
4472 if (!interpreterDeclarations.empty() &&
4473 interp.declare(interpreterDeclarations) != cling::Interpreter::kSuccess) {
4485 pcmArgs.push_back(linkdef);
4493 interp.AddIncludePath(inclPath);
4495 std::stringstream definesUndefinesStr;
4498 if (!definesUndefinesStr.str().empty())
4499 interp.declare(definesUndefinesStr.str());
4507 if (linkdef.empty()) {
4513 std::ofstream fileout;
4515 std::ostream *splitDictStream =
nullptr;
4516 std::unique_ptr<std::ostream> splitDeleter(
nullptr);
4518 tempFileNamesCatalog tmpCatalog;
4537 splitDeleter.reset(splitDictStream);
4539 splitDictStream = &dictStream;
4542 size_t dh = main_dictname.rfind(
'.');
4543 if (dh != std::string::npos) {
4544 main_dictname.erase(dh);
4547 std::string main_dictname_copy(main_dictname);
4566 string linkdefFilename;
4567 if (linkdef.empty()) {
4568 linkdefFilename =
"in memory";
4570 bool found =
Which(interp, linkdef.c_str(), linkdefFilename);
4578 std::vector<std::pair<std::string, std::string>> namesForExclusion;
4584 SelectionRules selectionRules(interp, normCtxt, namesForExclusion);
4586 std::string extraIncludes;
4591 const unsigned int selRulesInitialSize = selectionRules.
Size();
4593 ROOT::Internal::DictSelectionReader dictSelReader(interp, selectionRules, CI->getASTContext(), normCtxt);
4595 bool dictSelRulesPresent = selectionRules.
Size() > selRulesInitialSize;
4599 int rootclingRetCode(0);
4601 if (linkdef.empty()) {
4606 clingArgs.push_back(
"-Ietc/cling/cint");
4608 if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
4609 llvmResourceDir.c_str())) {
4611 rootclingRetCode += 1;
4621 }
else if (isSelXML) {
4625 std::ifstream
file(linkdefFilename.c_str());
4626 if (
file.is_open()) {
4630 if (!xmlr.
Parse(linkdefFilename.c_str(), selectionRules)) {
4643 std::ifstream
file(linkdefFilename.c_str());
4644 if (
file.is_open()) {
4654 clingArgs.push_back(
"-Ietc/cling/cint");
4656 if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
4657 llvmResourceDir.c_str())) {
4659 rootclingRetCode += 1;
4694 dictStream <<
"#include \"TBuffer.h\"\n"
4695 <<
"#include \"TVirtualObject.h\"\n"
4696 <<
"#include <vector>\n"
4697 <<
"#include \"TSchemaHelper.h\"\n\n";
4699 std::list<std::string> includes;
4701 for (
auto & incFile : includes) {
4702 dictStream <<
"#include <" << incFile <<
">" << std::endl;
4704 dictStream << std::endl;
4709 int scannerVerbLevel = 0;
4737 scan.
Scan(CI->getASTContext());
4739 bool has_input_error =
false;
4746 !dictSelRulesPresent &&
4753 if (rootclingRetCode)
return rootclingRetCode;
4760 if (annRcd.RequestNoInputOperator()) {
4772 if (has_input_error) {
4782 for (
auto &&includedFromLinkdef : filesIncludedByLinkdef) {
4783 includeForSource +=
"#include \"" + includedFromLinkdef +
"\"\n";
4802 constructorTypes.emplace_back(
"TRootIOCtor", interp);
4803 constructorTypes.emplace_back(
"__void__", interp);
4804 constructorTypes.emplace_back(
"", interp);
4834 if (rootclingRetCode != 0) {
4835 return rootclingRetCode;
4854 std::string detectedUmbrella;
4855 for (
auto & arg : pcmArgs) {
4857 detectedUmbrella = arg;
4863 headersDeclsMap.clear();
4867 std::string headersClassesMapString =
"\"\"";
4868 std::string fwdDeclsString =
"\"\"";
4884 if (modGen.
IsPCH()) {
4887 if (!
CheckModuleValid(modGen, llvmResourceDir, interp, linkdefFilename, moduleName.str()))
4897 ofstream outputfile(liblist_filename.c_str(), ios::out);
4900 executableFileName, liblist_filename.c_str());
4902 const size_t endStr =
gLibsNeeded.find_last_not_of(
" \t");
4903 outputfile <<
gLibsNeeded.substr(0, endStr + 1) << endl;
4905 outputfile <<
"# Now the list of classes\n";
4910 outputfile << annRcd.GetNormalizedName() << endl;
4917 if (0 != rootclingRetCode)
return rootclingRetCode;
4923 [](
const std::string &
a,
const std::string &
b) -> std::string {
4924 if (a.empty()) return b;
4925 else return a +
" " + b;
4930 std::list<std::string> classesNames;
4931 std::list<std::string> classesNamesForRootmap;
4932 std::list<std::string> classesDefsList;
4936 classesNamesForRootmap,
4940 std::list<std::string> enumNames;
4945 std::list<std::string> varNames;
4950 if (0 != rootclingRetCode)
return rootclingRetCode;
4953 if (rootMapNeeded) {
4955 std::list<std::string> nsNames;
4964 rootmapLibName.c_str());
4967 std::unordered_set<std::string> headersToIgnore;
4970 headersToIgnore.insert(optHeaderFileName.c_str());
4972 std::list<std::string> typedefsRootmapLines;
4980 classesNamesForRootmap,
4982 typedefsRootmapLines,
4988 if (0 != rootclingRetCode)
return 1;
4998 cling::Interpreter::PushTransactionRAII RAII(&interp);
4999 CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
5010 if(rootclingRetCode == 0) {
5011 rootclingRetCode += tmpCatalog.commit();
5016 return rootclingRetCode;
5027 unsigned int numberOfHeaders = 0;
5028 for (std::vector<std::string>::iterator it = headersNames.begin();
5029 it != headersNames.end(); ++it) {
5030 const std::string headername(*it);
5035 "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
5036 headername.c_str());
5039 return numberOfHeaders;
5045 unsigned int extractArgs(
int argc,
char **argv, std::vector<std::string> &args)
5048 unsigned int argvCounter = 0;
5049 for (
int i = 1; i < argc; ++i) {
5052 args.push_back(argv[i]);
5054 }
else if (argvCounter) {
5055 argv[i - argvCounter] = argv[i];
5062 std::cout <<
"Args: \n";
5063 for (std::vector<std::string>::iterator it = args.begin();
5064 it < args.end(); ++it) {
5065 std::cout << i <<
") " << *it << std::endl;
5078 size_t result = filename.find_last_of(
'.');
5079 if (std::string::npos != result) {
5080 filename.erase(result);
5081 filename.append(newExtension);
5091 const unsigned int size(str.size());
5092 char *
a =
new char[size + 1];
5094 memcpy(
a, str.c_str(), size);
5110 std::vector<std::string> &ofilesnames)
5112 ofilesnames.reserve(headersNames.size());
5114 for (std::vector<std::string>::const_iterator it = headersNames.begin();
5115 it != headersNames.end(); ++it) {
5116 std::string ofilename(*it);
5118 ofilesnames.push_back(ofilename);
5125 const std::vector<std::string> &argsToBeAdded,
5126 const std::string &optName =
"")
5128 for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
5129 it != argsToBeAdded.end(); ++it) {
5137 const std::vector<std::string> &argsToBeAdded,
5138 const std::string &optName =
"")
5140 for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
5141 it != argsToBeAdded.end(); ++it) {
5142 if (optName.length()) {
5152 const std::string &selectionFileName,
5153 const std::string &targetLibName,
5155 const std::vector<std::string> &pcmsNames,
5156 const std::vector<std::string> &includes,
5157 const std::vector<std::string> &preprocDefines,
5158 const std::vector<std::string> &preprocUndefines,
5159 const std::vector<std::string> &warnings,
5160 const std::string &rootmapFileName,
5161 const std::string &rootmapLibName,
5162 bool interpreteronly,
5165 bool writeEmptyRootPCM,
5167 bool noIncludePaths,
5168 bool noGlobalUsingStd,
5169 const std::vector<std::string> &headersNames,
5170 bool failOnWarnings,
5171 const std::string &ofilename)
5175 std::vector<char *> argvVector;
5186 std::string dictLocation;
5192 std::string newRootmapLibName(rootmapLibName);
5193 if (!rootmapFileName.empty() && newRootmapLibName.empty()) {
5194 if (headersNames.size() != 1) {
5196 "*** genreflex: No rootmap lib and several header specified!\n");
5199 newRootmapLibName =
"lib";
5200 newRootmapLibName += cleanHeaderName;
5206 std::string newRootmapFileName(rootmapFileName);
5207 if (!newRootmapFileName.empty() && !
HasPath(newRootmapFileName)) {
5208 newRootmapFileName = dictLocation + newRootmapFileName;
5213 if (!newRootmapFileName.empty()) {
5219 if (!newRootmapLibName.empty()) {
5225 if (interpreteronly)
5233 if (!targetLibName.empty()) {
5243 if (noGlobalUsingStd)
5253 if (writeEmptyRootPCM)
5276 if (!selectionFileName.empty()) {
5280 const int argc = argvVector.size();
5284 std::cout <<
"Rootcling commandline:\n";
5285 for (
int i = 0; i < argc; i++)
5286 std::cout << i <<
") " << argvVector[i] << std::endl;
5289 char **argv = & (argvVector[0]);
5294 for (
int i = 0; i < argc; i++)
5295 delete [] argvVector[i];
5297 return rootclingReturnCode;
5306 const std::string &selectionFileName,
5307 const std::string &targetLibName,
5309 const std::vector<std::string> &pcmsNames,
5310 const std::vector<std::string> &includes,
5311 const std::vector<std::string> &preprocDefines,
5312 const std::vector<std::string> &preprocUndefines,
5313 const std::vector<std::string> &warnings,
5314 const std::string &rootmapFileName,
5315 const std::string &rootmapLibName,
5316 bool interpreteronly,
5319 bool writeEmptyRootPCM,
5321 bool noIncludePaths,
5322 bool noGlobalUsingStd,
5323 const std::vector<std::string> &headersNames,
5324 bool failOnWarnings,
5325 const std::string &outputDirName_const =
"")
5327 std::string outputDirName(outputDirName_const);
5329 std::vector<std::string> ofilesNames;
5336 std::vector<std::string> namesSingleton(1);
5337 for (
unsigned int i = 0; i < headersNames.size(); ++i) {
5338 namesSingleton[0] = headersNames[i];
5339 std::string ofilenameFullPath(ofilesNames[i]);
5340 if (llvm::sys::path::parent_path(ofilenameFullPath) ==
"")
5341 ofilenameFullPath = outputDirName + ofilenameFullPath;
5363 if (returnCode != 0)
5378 std::vector<std::string> &values)
5381 if (options[oIndex]) {
5382 const int nVals = options[oIndex].count();
5383 values.reserve(nVals);
5384 int optionIndex = 0;
5387 << optionIndex <<
"/" << nVals <<
" "
5388 << opt->arg << std::endl;
5390 values.push_back(opt->arg);
5401 const char *descriptor)
5403 if (options[optionIndex]) {
5405 "*** genereflex: %s is not supported anymore.\n",
5493 enum optionTypes { NOTYPE, STRING } ;
5496 const char *genreflexUsage =
5497 "Generates dictionary sources and related ROOT pcm starting from an header.\n"
5498 "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n"
5501 const char *selectionFilenameUsage =
5502 "-s, --selection_file\tSelection filename\n"
5503 " Class selection file to specify for which classes the dictionary\n"
5504 " will be generated. The final set can be crafted with exclusion and\n"
5505 " exclusion rules.\n"
5506 " Properties can be specified. Some have special meaning:\n"
5507 " - name [string] name of the entity to select with an exact matching\n"
5508 " - pattern [string] name with wildcards (*) to select entities\n"
5509 " - file_name/file_pattern [string]: as name/pattern but referring to\n"
5510 " file where the C++ entities reside and not to C++ entities themselves.\n"
5511 " - transient/persistent [string: true/false] The fields to which they are\n"
5512 " applied will not be persistified if requested.\n"
5513 " - comment [string]: what you could write in code after an inline comment\n"
5514 " without \"//\". For example comment=\"!\" or \"||\".\n"
5515 " - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n"
5516 " Default value is 'false'\n"
5517 " - noInputOperator [true/false]: turns off input operator generation if set\n"
5518 " to 'true'. Default value is 'false'\n"
5522 " <class [name=\"classname\"] [pattern=\"wildname\"]\n"
5523 " [file_name=\"filename\"] [file_pattern=\"wildname\"]\n"
5524 " [id=\"xxxx\"] [noStreamer=\"true/false\"]\n"
5525 " [noInputOperator=\"true/false\"] />\n"
5526 " <class name=\"classname\" >\n"
5527 " <field name=\"m_transient\" transient=\"true\"/>\n"
5528 " <field name=\"m_anothertransient\" persistent=\"false\"/>\n"
5529 " <field name=\"m_anothertransient\" comment=\"||\"/>\n"
5530 " <properties prop1=\"value1\" [prop2=\"value2\"]/>\n"
5532 " <function [name=\"funcname\"] [pattern=\"wildname\"] />\n"
5533 " <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n"
5534 " <variable [name=\"varname\"] [pattern=\"wildname\"] />\n"
5537 " <class [name=\"classname\"] [pattern=\"wildname\"] />\n"
5538 " <method name=\"unwanted\" />\n"
5543 " If no selection file is specified, the class with the filename without\n"
5544 " extension will be selected, i.e. myClass.h as argument without any\n"
5545 " selection xml comes with an implicit selection rule for class \"myClass\".\n";
5547 const char *outputFilenameUsage =
5548 "-o, --output\tOutput filename\n"
5549 " Output file name. If an existing directory is specified instead of a file,\n"
5550 " then a filename will be build using the name of the input file and will\n"
5551 " be placed in the given directory. <headerfile>_rflx.cpp.\n"
5552 " NOTA BENE: the dictionaries that will be used within the same project must\n"
5553 " have unique names.\n";
5556 const char *targetLib =
5557 "-l, --library\tTarget library\n"
5558 " The flag -l must be followed by the name of the library that will\n"
5559 " contain the object file corresponding to the dictionary produced by\n"
5560 " this invocation of genreflex.\n"
5561 " The name takes priority over the one specified for the rootmapfile.\n"
5562 " The name influences the name of the created pcm:\n"
5563 " 1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n"
5564 " 2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n"
5565 " Any \"liblib\" occurence is transformed in the expected \"lib\".\n"
5566 " 3) If this is specified in conjunction with --multiDict, the output is\n"
5567 " libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
5569 const char *rootmapUsage =
5570 "--rootmap\tGenerate the rootmap file to be used by ROOT.\n"
5571 " This file lists the autoload keys. For example classes for which the\n"
5572 " reflection information is provided.\n"
5573 " The format of the rootmap is the following:\n"
5574 " - Forward declarations section\n"
5575 " - Libraries sections\n"
5576 " Rootmaps can be concatenated together, for example with the cat util.\n"
5577 " In order for ROOT to pick up the information in the rootmaps, they\n"
5578 " have to be located in the library path and have the .rootmap extension.\n"
5579 " An example rootmap file could be:\n"
5581 " template <class T> class A;\n"
5582 " [ libMyLib.so ]\n"
5583 " class A<double>\n"
5588 const char *rootmapLibUsage =
5589 "--rootmap-lib\tLibrary name for the rootmap file.\n";
5622 "--multiDict\tSupport for many dictionaries in one library\n"
5623 " Form correct pcm names if multiple dictionaries will be in the same\n"
5624 " library (needs target library switch. See its documentation).\n"
5631 "" ,
"noGlobalUsingStd" ,
5633 "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n"
5634 " All header files must have sumbols from std:: namespace fully qualified\n"
5640 "s" ,
"selection_file" ,
5642 selectionFilenameUsage
5656 "" ,
"rootmap-lib" ,
5664 "" ,
"interpreteronly",
5666 "--interpreteronly\tDo not generate I/O related information.\n"
5667 " Generate minimal dictionary required for interactivity.\n"
5675 "--split\tSplit the dictionary\n"
5676 " Split in two the dictionary, isolating the part with\n"
5677 " ClassDef related functions in a separate file.\n"
5685 "-m \tPcm file loaded before any header (option can be repeated).\n"
5693 "-v, --verbose\tPrint some debug information.\n"
5701 "--debug\tPrint all debug information.\n"
5709 "--quiet\tPrint only warnings and errors (default).\n"
5717 "--silent\tPrint no information at all.\n"
5723 "" ,
"writeEmptyPCM",
5725 "--writeEmptyPCM\tWrite an empty ROOT pcm.\n"
5733 "--cxxmodule\tGenerates a PCM for C++ Modules.\n"
5742 "--help\tPrint usage and exit.\n"
5748 "",
"fail_on_warnings",
5750 "--fail_on_warnings\tFail on warnings and errors.\n"
5756 "",
"selSyntaxOnly",
5758 "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n"
5764 "" ,
"noIncludePaths",
5766 "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n"
5805 "" ,
"no_membertypedefs" ,
5813 "" ,
"no_templatetypedefs" ,
5821 std::vector<std::string> headersNames;
5822 const int originalArgc = argc;
5824 const int extractedArgs =
extractArgs(argc, argv, headersNames);
5826 const int offset = 1;
5827 argc -= offset + extractedArgs;
5832 std::vector<ROOT::option::Option> options(stats.
options_max);
5833 std::vector<ROOT::option::Option> buffer(stats.
buffer_max);
5839 if (parse.
error()) {
5845 if (options[HELP] || originalArgc == 1) {
5851 if (0 == numberOfHeaders) {
5862 std::string verbosityOption(
"-v2");
5863 if (options[SILENT]) verbosityOption =
"-v0";
5864 if (options[
VERBOSE] || getenv (
"VERBOSE")) verbosityOption =
"-v3";
5865 if (options[
DEBUG]) verbosityOption =
"-v4";
5870 std::string selectionFileName;
5871 if (options[SELECTIONFILENAME]) {
5872 selectionFileName = options[SELECTIONFILENAME].arg;
5875 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
5876 selectionFileName.c_str());
5891 std::string rootmapFileName(options[ROOTMAP].arg ? options[ROOTMAP].arg :
"");
5892 std::string rootmapLibName(options[ROOTMAPLIB].arg ? options[ROOTMAPLIB].arg :
"");
5895 std::string targetLibName;
5896 if (options[TARGETLIB]) {
5897 targetLibName = options[TARGETLIB].arg;
5900 "Invalid target library extension: filename is %s and extension %s is expected!\n",
5901 targetLibName.c_str(),
5905 if (options[ROOTMAP]) {
5910 bool isCxxmodule = options[CXXMODULE];
5912 bool multidict =
false;
5913 if (options[MULTIDICT]) multidict =
true;
5915 bool noGlobalUsingStd =
false;
5916 if (options[NOGLOBALUSINGSTD]) noGlobalUsingStd =
true;
5918 if (multidict && targetLibName.empty()) {
5920 "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
5924 bool interpreteronly =
false;
5925 if (options[INTERPRETERONLY])
5926 interpreteronly =
true;
5928 bool doSplit =
false;
5932 bool writeEmptyRootPCM =
false;
5933 if (options[WRITEEMPTYROOTPCM])
5934 writeEmptyRootPCM =
true;
5936 bool selSyntaxOnly =
false;
5937 if (options[SELSYNTAXONLY]) {
5938 selSyntaxOnly =
true;
5941 bool noIncludePaths =
false;
5942 if (options[NOINCLUDEPATHS]) {
5943 noIncludePaths =
true;
5946 bool failOnWarnings =
false;
5947 if (options[FAILONWARNINGS]) {
5948 failOnWarnings =
true;
5957 std::vector<std::string> pcmsNames;
5961 std::vector<std::string> preprocDefines;
5965 std::vector<std::string> preprocUndefines;
5969 std::vector<std::string> includes;
5973 std::vector<std::string> warnings;
5984 int returnValue = 0;
5985 std::string ofileName(options[OFILENAME] ? options[OFILENAME].arg :
"");
5989 if (!ofileName.empty() && !llvm::sys::fs::is_directory(ofileName)) {
6046 assert(!
gDriverConfig &&
"Driver configuration already set!");
6060 if (std::string::npos != exeName.find(
"genreflex"))
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.
void Info(const char *location, const char *msgfmt,...)
const AttributesMap_t & GetAttributes() const
std::unordered_map< std::string, std::string > AttributesMap_t
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.
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.
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
RooAbsArg * find(const char *name) const
Find object with given name in list.
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)
bool Parse(const std::string &fileName, SelectionRules &out)
static bool FromCygToNativePath(std::string &path)
Type
enumeration specifying the integration types.
EvaluateInfo init(std::vector< RooRealProxy > parameters, std::vector< ArrayWrapper * > wrappers, std::vector< double * > arrays, size_t begin, size_t batchSize)
std::string GetCurrentDir()
std::string MakePathRelative(const std::string &path, const std::string &base, bool isBuildingROOT=false)
auto Map(Args &&... args) -> decltype(ROOT::Detail::VecOps::MapFromTuple(std::forward_as_tuple(args...), std::make_index_sequence< sizeof...(args) - 1 >()))
Create new collection applying a callable to the elements of the input collection.
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
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
RooArgSet S(const RooAbsArg &v1)
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
static constexpr double s
static constexpr double ns
static constexpr double second
constexpr Double_t E()
Base of natural log:
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...
bool ParsePragmaLine(const std::string &line, const char *expectedTokens[], size_t *end=0)
Check whether the #pragma line contains expectedTokens (0-terminated array).
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))
map< string, string > gAutoloads
static llvm::cl::opt< bool > gOptCheckSelectionSyntax("selSyntaxOnly", llvm::cl::desc("Check the selection syntax only."), llvm::cl::cat(gRootclingOptions))
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 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")
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)
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 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.
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)
int ROOT_rootcling_Driver(int argc, char **argv, const ROOT::Internal::RootCling::DriverConfig &config)
bool IsGoodForAutoParseMap(const clang::RecordDecl &rcd)
Check if the class good for being an autoparse key.
void GetMostExternalEnclosingClassNameFromDecl(const clang::Decl &theDecl, std::string &ctxtName, const cling::Interpreter &interpreter)
static llvm::cl::opt< bool > gOptP("p", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::cat(gRootclingOptions))
void SetRootSys()
Set the ROOTSYS env var based on the executable location.
bool CheckInputOperator(const char *what, const char *proto, const string &fullname, const clang::RecordDecl *cl, cling::Interpreter &interp)
Check if the specified operator (what) has been properly declared if the user has requested a custom ...
void GenerateNecessaryIncludes(std::ostream &dictStream, const std::string &includeForSource, const std::string &extraIncludes)
void StrcpyArg(string &dest, const char *original)
Copy the command line argument, stripping MODULE/inc if necessary.
static llvm::cl::list< std::string > gOptRootmapLibNames("rml", llvm::cl::ZeroOrMore, llvm::cl::desc("Generate rootmap file."), llvm::cl::cat(gRootclingOptions))
void ParseRootMapFile(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map.
static llvm::cl::opt< bool > gOptCxxModule("cxxmodule", llvm::cl::desc("Generate a C++ module."), llvm::cl::cat(gRootclingOptions))
std::pair< std::string, std::string > GetExternalNamespaceAndContainedEntities(const std::string line)
Performance is not critical here.
void AddPlatformDefines(std::vector< std::string > &clingArgs)
static std::string GenerateFwdDeclString(const RScanner &scan, const cling::Interpreter &interp)
Generate the fwd declarations of the selected entities.
static llvm::cl::opt< bool > gOptFailOnWarnings("failOnWarnings", llvm::cl::desc("Fail if there are warnings."), llvm::cl::cat(gRootclingOptions))
const char * CopyArg(const char *original)
If the argument starts with MODULE/inc, strip it to make it the name we can use in #includes.
string GetNonConstMemberName(const clang::FieldDecl &m, const string &prefix="")
Return the name of the data member so that it can be used by non-const operation (so it includes a co...
static llvm::cl::list< std::string > gOptIncludePaths("I", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify an include path."), llvm::cl::cat(gRootclingOptions))
void WriteAutoStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
void ExtractSelectedNamespaces(RScanner &scan, std::list< std::string > &nsList)
Loop on selected classes and put them in a list.
static bool IncludeHeaders(const std::vector< std::string > &headers, cling::Interpreter &interpreter)
Includes all given headers in the interpreter.
clang::QualType GetPointeeTypeIfPossible(const clang::QualType &qt)
Get the pointee type if possible.
void AnnotateDecl(clang::CXXRecordDecl &CXXRD, const RScanner::DeclsSelRulesMap_t &declSelRulesMap, cling::Interpreter &interpreter, bool isGenreflex)
static llvm::cl::opt< VerboseLevel > gOptVerboseLevel(llvm::cl::desc("Choose verbosity level:"), llvm::cl::values(clEnumVal(v, "Show errors."), clEnumVal(v0, "Show only fatal errors."), clEnumVal(v1, "Show errors (the same as -v)."), clEnumVal(v2, "Show warnings (default)."), clEnumVal(v3, "Show notes."), clEnumVal(v4, "Show information.")), llvm::cl::init(v2), llvm::cl::cat(gRootclingOptions))
void GenerateLinkdef(llvm::cl::list< std::string > &InputFiles, std::string &code_for_parser)
static llvm::cl::opt< std::string > gOptDictionaryFileName(llvm::cl::Positional, llvm::cl::Required, llvm::cl::desc("<output dictionary file>"), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< std::string > gOptRootMapFileName("rmf", llvm::cl::desc("Generate a rootmap file with the specified name."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::opt< bool > gOptInlineInput("inlineInputHeader", llvm::cl::desc("Does not generate #include <header> but expands the header content."), llvm::cl::cat(gRootclingOptions))
bool isPointerToPointer(const clang::FieldDecl &m)
static bool WriteAST(StringRef fileName, clang::CompilerInstance *compilerInstance, StringRef iSysRoot, clang::Module *module=nullptr)
Write the AST of the given CompilerInstance to the given File while respecting the given isysroot.
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...
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))
static llvm::cl::opt< bool > gOptMultiDict("multiDict", llvm::cl::desc("If this library has multiple separate LinkDef files."), llvm::cl::cat(gRootclingOptions))
static llvm::cl::list< std::string > gOptDictionaryHeaderFiles(llvm::cl::Positional, llvm::cl::OneOrMore, llvm::cl::desc("<list of dictionary header files> <LinkDef file>"), 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 bool ModuleContainsHeaders(TModuleGenerator &modGen, clang::Module *module, std::vector< std::string > &missingHeaders)
Returns true iff a given module (and its submodules) contains all headers needed by the given ModuleG...
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.
llvm::StringRef GrabIndex(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 void EmitEnums(const std::vector< const clang::EnumDecl * > &enumvec)
static bool CheckModuleValid(TModuleGenerator &modGen, const std::string &resourceDir, cling::Interpreter &interpreter, StringRef LinkdefPath, const std::string &moduleName)
Check moduleName validity from modulemap. Check if this module is defined or not.
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.
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)