12#include "rootclingCommandLineOptionsHelp.h" 
   14#include "RConfigure.h" 
   33#include <unordered_map> 
   34#include <unordered_set> 
   46#define PATH_MAX _MAX_PATH 
   54#include <mach-o/dyld.h> 
   63#include "cling/Interpreter/Interpreter.h" 
   64#include "cling/Interpreter/InterpreterCallbacks.h" 
   65#include "cling/Interpreter/LookupHelper.h" 
   66#include "cling/Interpreter/Value.h" 
   67#include "clang/AST/CXXInheritance.h" 
   68#include "clang/Basic/Diagnostic.h" 
   69#include "clang/Frontend/CompilerInstance.h" 
   70#include "clang/Frontend/FrontendActions.h" 
   71#include "clang/Frontend/FrontendDiagnostic.h" 
   72#include "clang/Lex/HeaderSearch.h" 
   73#include "clang/Lex/Preprocessor.h" 
   74#include "clang/Lex/ModuleMap.h" 
   75#include "clang/Lex/Pragma.h" 
   76#include "clang/Sema/Sema.h" 
   77#include "clang/Serialization/ASTWriter.h" 
   78#include "cling/Utils/AST.h" 
   80#include "llvm/ADT/StringRef.h" 
   82#include "llvm/Support/CommandLine.h" 
   83#include "llvm/Support/Path.h" 
   84#include "llvm/Support/PrettyStackTrace.h" 
   85#include "llvm/Support/Signals.h" 
  109#include <mach-o/dyld.h> 
  114#define strcasecmp _stricmp 
  115#define strncasecmp _strnicmp 
  141static llvm::cl::opt<bool>
 
  143               llvm::cl::desc(
"Deprecated. Similar to -f but it ignores the dictionary generation. \ 
  144When -r is present rootcling becomes a tool to generate rootmaps (and capability files)."),
 
  164static void EmitTypedefs(
const std::vector<const clang::TypedefNameDecl *> &tdvec)
 
  168   for (
const auto td : tdvec)
 
  171static void EmitEnums(
const std::vector<const clang::EnumDecl *> &enumvec)
 
  175   for (
const auto en : enumvec) {
 
  177      if (clang::isa<clang::TranslationUnitDecl>(en->getDeclContext())
 
  178            || clang::isa<clang::LinkageSpecDecl>(en->getDeclContext())
 
  179            || clang::isa<clang::NamespaceDecl>(en->getDeclContext()))
 
  189  static std::string exepath;
 
  192    exepath = _dyld_get_image_name(0);
 
  194#if defined(__linux) || defined(__linux__) 
  195    char linkname[PATH_MAX];  
 
  201    snprintf(linkname, PATH_MAX, 
"/proc/%i/exe", pid);
 
  202    int ret = readlink(linkname, buf, 1024);
 
  203    if (ret > 0 && ret < 1024) {
 
  209    char *buf = 
new char[MAX_MODULE_NAME32 + 1];
 
  210      ::GetModuleFileName(NULL, buf, MAX_MODULE_NAME32 + 1);
 
  212      while ((p = strchr(p, 
'\\')))
 
  218  return exepath.c_str();
 
  224                          const cling::Interpreter &interp)
 
  232                              const std::list<VariableSelectionRule> &fieldSelRules)
 
  240   if (fieldSelRules.empty()) 
return;
 
  242   clang::ASTContext &C = decl.getASTContext();
 
  243   clang::SourceRange commentRange; 
 
  245   const std::string declName(decl.getNameAsString());
 
  247   for (std::list<VariableSelectionRule>::const_iterator it = fieldSelRules.begin();
 
  248         it != fieldSelRules.end(); ++it) {
 
  249      if (! it->GetAttributeValue(propNames::name, varName)) 
continue;
 
  250      if (declName == varName) { 
 
  253         BaseSelectionRule::AttributesMap_t::iterator iter;
 
  254         std::string userDefinedProperty;
 
  255         for (iter = attrMap.begin(); iter != attrMap.end(); ++iter) {
 
  256            const std::string &
name = iter->first;
 
  257            const std::string &value = iter->second;
 
  259            if (
name == propNames::name) 
continue;
 
  264            if (
name == propNames::iotype &&
 
  265                  (decl.getType()->isArrayType() ||  decl.getType()->isPointerType())) {
 
  266               const char *msg = 
"Data member \"%s\" is an array or a pointer. " 
  267                                 "It is not possible to assign to it the iotype \"%s\". " 
  268                                 "This transformation is possible only with data members " 
  269                                 "which are not pointers or arrays.\n";
 
  271                                       msg, varName.c_str(), value.c_str());
 
  279            if (
name == propNames::comment) {
 
  280               decl.addAttr(
new(C) clang::AnnotateAttr(commentRange, C, value, 0));
 
  284            if ((
name == propNames::transient && value == 
"true") ||
 
  285                  (
name == propNames::persistent && value == 
"false")) { 
 
  286               userDefinedProperty = propNames::comment + propNames::separator + 
"!";
 
  290               decl.addAttr(
new(C) clang::AnnotateAttr(commentRange, C, 
"!", 0));
 
  295               userDefinedProperty = 
name + propNames::separator + value;
 
  298            decl.addAttr(
new(C) clang::AnnotateAttr(commentRange, C, userDefinedProperty, 0));
 
  309                  cling::Interpreter &interpreter,
 
  317   using namespace clang;
 
  318   SourceLocation commentSLoc;
 
  319   llvm::StringRef comment;
 
  321   ASTContext &C = CXXRD.getASTContext();
 
  322   Sema &S = interpreter.getCI()->getSema();
 
  324   SourceRange commentRange;
 
  327   clang::Decl *declBaseClassPtr = 
static_cast<clang::Decl *
>(&CXXRD);
 
  328   auto declSelRulePair = declSelRulesMap.
find(declBaseClassPtr->getCanonicalDecl());
 
  329   if (declSelRulePair == declSelRulesMap.end()){
 
  330      const std::string thisClassName(CXXRD.getName());
 
  331      ROOT::TMetaUtils::Error(
"AnnotateDecl",
"Cannot find class %s in the list of selected classes.\n",thisClassName.c_str());
 
  336   if (thisClassBaseSelectionRule) {
 
  339      BaseSelectionRule::AttributesMap_t::iterator iter;
 
  340      std::string userDefinedProperty;
 
  341      for (
auto const & attr : thisClassBaseSelectionRule->
GetAttributes()) {
 
  342         const std::string &
name = attr.first;
 
  344         const std::string &value = attr.second;
 
  347         CXXRD.addAttr(
new(C) AnnotateAttr(commentRange, C, userDefinedProperty, 0));
 
  354   for (CXXRecordDecl::decl_iterator 
I = CXXRD.decls_begin(),
 
  355         E = CXXRD.decls_end(); 
I != E; ++
I) {
 
  359      if (!(*I)->isImplicit()
 
  360            && (isa<CXXMethodDecl>(*
I) || isa<FieldDecl>(*
I) || isa<VarDecl>(*
I))) {
 
  364         SourceLocation maybeMacroLoc = (*I)->getLocation();
 
  365         bool isClassDefMacro = maybeMacroLoc.isMacroID() && S.findMacroSpelling(maybeMacroLoc, 
"ClassDef");
 
  366         if (isClassDefMacro) {
 
  367            while (isa<NamedDecl>(*
I) && cast<NamedDecl>(*I)->getName() != 
"DeclFileLine") {
 
  373         if (comment.size()) {
 
  376            commentRange = SourceRange(commentSLoc, commentSLoc.getLocWithOffset(comment.size()));
 
  378            if (isClassDefMacro) {
 
  379               CXXRD.addAttr(
new(C) AnnotateAttr(commentRange, C, comment.str(), 0));
 
  380            } 
else if (!isGenreflex) {
 
  386               (*I)->addAttr(
new(C) AnnotateAttr(commentRange, C, comment.str(), 0));
 
  391         if (isGenreflex && thisClassSelectionRule != 
nullptr) {
 
  395            if (FieldDecl *fieldDecl  = dyn_cast<FieldDecl>(*
I)) {
 
  409   llvm::APInt len = arrayType->getSize();
 
  410   while (
const clang::ConstantArrayType *subArrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual())) {
 
  411      len *= subArrayType->getSize();
 
  412      arrayType = subArrayType;
 
  414   return len.getLimitedValue();
 
  420                         const cling::Interpreter &interp)
 
  422   static const clang::CXXRecordDecl *TObject_decl
 
  425   const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
 
  432                           const cling::Interpreter &interp)
 
  434   static const clang::CXXRecordDecl *TObject_decl
 
  444   size_t len = strlen(filename);
 
  446   if (strlen(filename) >= xmllen) {
 
  447      return (0 == strcasecmp(filename + (len - xmllen), 
".xml"));
 
  473   if (exepath && *exepath) {
 
  475      char *ep = 
new char[PATH_MAX];
 
  476      if (!realpath(exepath, ep)) {
 
  477         fprintf(stderr, 
"rootcling: error getting realpath of rootcling!");
 
  478         strlcpy(ep, exepath, PATH_MAX);
 
  481      int nche = strlen(exepath) + 1;
 
  482      char *ep = 
new char[nche];
 
  483      strlcpy(ep, exepath, nche);
 
  487      if ((s = strrchr(ep, 
'/'))) {
 
  489         int removesubdirs = 2;
 
  490         if (!strncmp(s + 1, 
"rootcling_stage1.exe", 20)) {
 
  494         } 
else if (!strncmp(s + 1, 
"rootcling_stage1", 16)) {
 
  499         for (
int i = 1; s && i < removesubdirs; ++i) {
 
  501            s = strrchr(ep, 
'/');
 
  515      int ncha = strlen(ep) + 10;
 
  516      char *env = 
new char[ncha];
 
  517      snprintf(env, ncha, 
"ROOTSYS=%s", ep);
 
  538                     const char *expectedTokens[],
 
  539                     size_t *end = 
nullptr)
 
  542   if (
line[0] != 
'#') 
return false;
 
  544   for (
const char **iToken = expectedTokens; *iToken; ++iToken) {
 
  545      while (isspace(
line[pos])) ++pos;
 
  546      size_t lenToken = strlen(*iToken);
 
  547      if (
line.compare(pos, lenToken, *iToken)) {
 
  566   if (recordDecl->hasOwningModule()) {
 
  567      clang::Module *M = recordDecl->getOwningModule()->getTopLevelModule();
 
  570      std::string qual_name;
 
  576   if (need.length() && 
gLibsNeeded.find(need) == string::npos) {
 
  585   if (classname.find(
':') == std::string::npos) 
return;
 
  588   int slen = classname.size();
 
  589   for (
int k = 0; k < slen; ++k) {
 
  590      if (classname[k] == 
':') {
 
  591         if (k + 1 >= slen || classname[k + 1] != 
':') {
 
  596            string base = classname.substr(0, k);
 
  601               autoloads[base] = 
""; 
 
  605      } 
else if (classname[k] == 
'<') {
 
  617   std::string classname;
 
  621      if (
line.find(
"Library.") != 0) 
continue;
 
  623      int pos = 
line.find(
":", 8);
 
  624      classname = 
line.substr(8, pos - 8);
 
  630      while (
line[0] == 
' ') 
line.replace(0, 1, 
"");
 
  634      if (classname == 
"ROOT::TImpProxy") {
 
  638      autoloads[classname] = 
line;
 
  653   const std::unordered_map<char, unsigned int> keyLenMap = {{
'c', 6}, {
'n', 10}, {
't', 8}};
 
  656      if (
line == 
"{ decls }") {
 
  658            if (
line[0] == 
'[') 
break;
 
  661      const char firstChar = 
line[0];
 
  662      if (firstChar == 
'[') {
 
  664         libs = 
line.substr(1, 
line.find(
']') - 1);
 
  665         while (libs[0] == 
' ') libs.replace(0, 1, 
"");
 
  666      } 
else if (0 != keyLenMap.count(firstChar)) {
 
  667         unsigned int keyLen = keyLenMap.at(firstChar);
 
  668         keyname = 
line.substr(keyLen, 
line.length() - keyLen);
 
  670         autoloads[keyname] = libs;
 
  680void LoadLibraryMap(
const std::string &fileListName, map<string, string> &autoloads)
 
  682   std::ifstream filelist(fileListName.c_str());
 
  684   std::string filename;
 
  687   while (filelist >> filename) {
 
  689      if (llvm::sys::fs::is_directory(filename)) 
continue;
 
  691      ifstream 
file(filename.c_str());
 
  695      bool new_format = (
line[0] == 
'[' || 
line[0] == 
'{') ;
 
  697      file.seekg(0, std::ios::beg);
 
  718                        const string &fullname,
 
  719                        const clang::RecordDecl *cl,
 
  720                        cling::Interpreter &interp)
 
  723   const clang::FunctionDecl *method
 
  728      clang::TranslationUnitDecl *TU =
 
  729         cl->getASTContext().getTranslationUnitDecl();
 
  733   bool has_input_error = 
false;
 
  734   if (method != 
nullptr && (method->getAccess() == clang::AS_public || method->getAccess() == clang::AS_none)) {
 
  736      if (strstr(filename.c_str(), 
"TBuffer.h") != 
nullptr ||
 
  737            strstr(filename.c_str(), 
"Rtypes.h") != 
nullptr) {
 
  739         has_input_error = 
true;
 
  742      has_input_error = 
true;
 
  744   if (has_input_error) {
 
  746      const char *maybeconst = 
"";
 
  747      const char *mayberef = 
"&";
 
  748      if (
what[strlen(
what) - 1] == 
'<') {
 
  749         maybeconst = 
"const ";
 
  753                              "in this version of ROOT, the option '!' used in a linkdef file\n" 
  754                              "       implies the actual existence of customized operators.\n" 
  755                              "       The following declaration is now required:\n" 
  756                              "   TBuffer &%s(TBuffer &,%s%s *%s);\n", 
what, maybeconst, fullname.c_str(), mayberef);
 
  758   return has_input_error;
 
  770   int ncha = fullname.length() + 13;
 
  771   char *
proto = 
new char[ncha];
 
  783   return has_input_error;
 
  789bool CheckClassDef(
const clang::RecordDecl &cl, 
const cling::Interpreter &interp)
 
  795   const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(&cl);
 
  799   bool isAbstract = clxx->isAbstract();
 
  802      std::string qualName;
 
  804      const char *qualName_c = qualName.c_str();
 
  806                                            "because it inherits from TObject but does not " 
  807                                            "have its own ClassDef.\n",
 
  820   if (
m.getType().isConstQualified()) {
 
  821      string ret = 
"const_cast< ";
 
  824      if (type_name.substr(0,6)==
"const ") {
 
  825         ret += type_name.c_str()+6;
 
  831      ret += 
m.getName().str();
 
  835      return prefix + 
m.getName().str();
 
  845                         const cling::Interpreter &interp,
 
  847                         std::ostream &dictStream)
 
  850   std::string mTypename;
 
  863   if (!clxx || clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared) 
return 0;
 
  865   const clang::ClassTemplateSpecializationDecl *tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (clxx);
 
  866   if (!tmplt_specialization) 
return 0;
 
  872   string fulName1, fulName2;
 
  873   const char *tcl1 = 
nullptr, *tcl2 = 
nullptr;
 
  874   const clang::TemplateArgument &arg0(tmplt_specialization->getTemplateArgs().get(0));
 
  875   clang::QualType ti = arg0.getAsType();
 
  879      fulName1 = ti.getAsString(); 
 
  882      const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
 
  883      clang::QualType tmplti = arg1.getAsType();
 
  886         fulName2 = tmplti.getAsString(); 
 
  893   const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
 
  899         if (arrayType->getArrayElementTypeNoTypeQual()->isPointerType()) {
 
  903         arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
 
  905   } 
else if (
m.getType()->isPointerType()) {
 
  910      dictStream << 
"      {" << std::endl;
 
  912         dictStream << 
"         for (Int_t R__l = 0; R__l < " << len << 
"; R__l++) {" << std::endl;
 
  917            dictStream << 
"         " << stlType.c_str() << 
" &R__stl =  " << stlName.c_str() << 
";" << std::endl;
 
  920            dictStream << 
"         " << stlType.c_str() << 
" &R__stl =  " << stlName.c_str() << 
"[R__l];" << std::endl;
 
  923            dictStream << 
"         delete *" << stlName.c_str() << 
";" << std::endl
 
  924                       << 
"         *" << stlName.c_str() << 
" = new " << stlType.c_str() << 
";" << std::endl
 
  925                       << 
"         " << stlType.c_str() << 
" &R__stl = **" << stlName.c_str() << 
";" << std::endl;
 
  928            dictStream << 
"         delete " << stlName.c_str() << 
"[R__l];" << std::endl
 
  929                       << 
"         " << stlName.c_str() << 
"[R__l] = new " << stlType.c_str() << 
";" << std::endl
 
  930                       << 
"         " << stlType.c_str() << 
" &R__stl = *" << stlName.c_str() << 
"[R__l];" << std::endl;
 
  934      dictStream << 
"         R__stl.clear();" << std::endl;
 
  937         dictStream << 
"         TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() << 
"));" << std::endl
 
  938                    << 
"         if (R__tcl1==0) {" << std::endl
 
  939                    << 
"            Error(\"" << stlName.c_str() << 
" streamer\",\"Missing the TClass object for " 
  940                    << fulName1.c_str() << 
"!\");"  << std::endl
 
  941                    << 
"            return;" << std::endl
 
  942                    << 
"         }" << std::endl;
 
  945         dictStream << 
"         TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() << 
"));" << std::endl
 
  946                    << 
"         if (R__tcl2==0) {" << std::endl
 
  947                    << 
"            Error(\"" << stlName.c_str() << 
" streamer\",\"Missing the TClass object for " 
  948                    << fulName2.c_str() << 
"!\");" << std::endl
 
  949                    << 
"            return;" << std::endl
 
  950                    << 
"         }" << std::endl;
 
  953      dictStream << 
"         int R__i, R__n;" << std::endl
 
  954                 << 
"         R__b >> R__n;" << std::endl;
 
  957         dictStream << 
"         R__stl.reserve(R__n);" << std::endl;
 
  959      dictStream << 
"         for (R__i = 0; R__i < R__n; R__i++) {" << std::endl;
 
  963         const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
 
  983               std::string keyName(ti.getAsString());
 
  984               dictStream << 
"            typedef " << keyName << 
" Value_t;" << std::endl
 
  985                          << 
"            std::pair<Value_t const, " << tmplt_specialization->getTemplateArgs().get(1).getAsType().getAsString() << 
" > R__t3(R__t,R__t2);" << std::endl
 
  986                          << 
"            R__stl.insert(R__t3);" << std::endl;
 
  994            dictStream << 
"            R__stl.insert(R__t);" << std::endl;
 
  999            dictStream << 
"            R__stl.push_back(R__t);" << std::endl;
 
 1002            dictStream << 
"            R__stl.push_front(R__t);" << std::endl;
 
 1007      dictStream << 
"         }" << std::endl
 
 1008                 << 
"      }" << std::endl;
 
 1009      if (isArr) dictStream << 
"    }" << std::endl;
 
 1015         dictStream << 
"         for (Int_t R__l = 0; R__l < " << len << 
"; R__l++) {" << std::endl;
 
 1017      dictStream << 
"      {" << std::endl;
 
 1020            dictStream << 
"         " << stlType.c_str() << 
" &R__stl =  " << stlName.c_str() << 
";" << std::endl;
 
 1023            dictStream << 
"         " << stlType.c_str() << 
" &R__stl =  " << stlName.c_str() << 
"[R__l];" << std::endl;
 
 1026            dictStream << 
"         " << stlType.c_str() << 
" &R__stl = **" << stlName.c_str() << 
";" << std::endl;
 
 1029            dictStream << 
"         " << stlType.c_str() << 
" &R__stl = *" << stlName.c_str() << 
"[R__l];" << std::endl;
 
 1033      dictStream << 
"         int R__n=int(R__stl.size());" << std::endl
 
 1034                 << 
"         R__b << R__n;" << std::endl
 
 1035                 << 
"         if(R__n) {" << std::endl;
 
 1038         dictStream << 
"         TClass *R__tcl1 = TBuffer::GetClass(typeid(" << fulName1.c_str() << 
"));" << std::endl
 
 1039                    << 
"         if (R__tcl1==0) {" << std::endl
 
 1040                    << 
"            Error(\"" << stlName.c_str() << 
" streamer\",\"Missing the TClass object for " 
 1041                    << fulName1.c_str() << 
"!\");" << std::endl
 
 1042                    << 
"            return;" << std::endl
 
 1043                    << 
"         }" << std::endl;
 
 1046         dictStream << 
"         TClass *R__tcl2 = TBuffer::GetClass(typeid(" << fulName2.c_str() << 
"));" << std::endl
 
 1047                    << 
"         if (R__tcl2==0) {" << std::endl
 
 1048                    << 
"            Error(\"" << stlName.c_str() << 
"streamer\",\"Missing the TClass object for " << fulName2.c_str() << 
"!\");" << std::endl
 
 1049                    << 
"            return;" << std::endl
 
 1050                    << 
"         }" << std::endl;
 
 1053      dictStream << 
"            " << stlType.c_str() << 
"::iterator R__k;" << std::endl
 
 1054                 << 
"            for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {" << std::endl;
 
 1056         const clang::TemplateArgument &arg1(tmplt_specialization->getTemplateArgs().get(1));
 
 1057         clang::QualType tmplti = arg1.getAsType();
 
 1064      dictStream << 
"            }" << std::endl
 
 1065                 << 
"         }" << std::endl
 
 1066                 << 
"      }" << std::endl;
 
 1067      if (isArr) dictStream << 
"    }" << std::endl;
 
 1079   std::string mTypenameStr;
 
 1083   if (!strcmp(mTypeName, 
"string")) {
 
 1085      std::string fieldname =  
m.getName().str();
 
 1088         if (
m.getType()->isConstantArrayType()) {
 
 1089            if (
m.getType().getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
 
 1090               dictStream << 
"// Array of pointer to std::string are not supported (" << fieldname << 
"\n";
 
 1092               std::stringstream fullIdx;
 
 1093               const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
 
 1096                  dictStream << 
"      for (int R__i" << dim << 
"=0; R__i" << dim << 
"<" 
 1097                             << arrayType->getSize().getLimitedValue() << 
"; ++R__i" << dim << 
" )" << std::endl;
 
 1098                  fullIdx << 
"[R__i" << dim << 
"]";
 
 1099                  arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
 
 1102               dictStream << 
"         { TString R__str; R__str.Streamer(R__b); " 
 1103                          << fieldname << fullIdx.str() << 
" = R__str.Data();}" << std::endl;
 
 1106            dictStream << 
"      { TString R__str; R__str.Streamer(R__b); ";
 
 1107            if (
m.getType()->isPointerType())
 
 1108               dictStream << 
"if (*" << fieldname << 
") delete *" << fieldname << 
"; (*" 
 1109                          << fieldname << 
" = new string(R__str.Data())); }" << std::endl;
 
 1111               dictStream << fieldname << 
" = R__str.Data(); }" << std::endl;
 
 1115         if (
m.getType()->isPointerType())
 
 1116            dictStream << 
"      { TString R__str; if (*" << fieldname << 
") R__str = (*" 
 1117                       << fieldname << 
")->c_str(); R__str.Streamer(R__b);}" << std::endl;
 
 1118         else if (
m.getType()->isConstantArrayType()) {
 
 1119            std::stringstream fullIdx;
 
 1120            const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
m.getType().getTypePtr());
 
 1123               dictStream << 
"      for (int R__i" << dim << 
"=0; R__i" << dim << 
"<" 
 1124                          << arrayType->getSize().getLimitedValue() << 
"; ++R__i" << dim << 
" )" << std::endl;
 
 1125               fullIdx << 
"[R__i" << dim << 
"]";
 
 1126               arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
 
 1129            dictStream << 
"         { TString R__str(" << fieldname << fullIdx.str() << 
".c_str()); R__str.Streamer(R__b);}" << std::endl;
 
 1131            dictStream << 
"      { TString R__str = " << fieldname << 
".c_str(); R__str.Streamer(R__b);}" << std::endl;
 
 1142   if (
m.getType()->isPointerType()) {
 
 1143      if (
m.getType()->getPointeeType()->isPointerType()) {
 
 1155   const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
 
 1157      arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
 
 1159         dictStream << 
"[0]";
 
 1160         arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
 
 1175   int enclSpaceNesting = 0;
 
 1182      dictStream << 
"#include \"TInterpreter.h\"\n";
 
 1184   dictStream << 
"//_______________________________________" 
 1185              << 
"_______________________________________" << std::endl;
 
 1186   if (add_template_keyword) dictStream << 
"template <> ";
 
 1187   dictStream << 
"atomic_TClass_ptr " << clsname << 
"::fgIsA(nullptr);  // static to hold class pointer" << std::endl
 
 1190              << 
"//_______________________________________" 
 1191              << 
"_______________________________________" << std::endl;
 
 1192   if (add_template_keyword) dictStream << 
"template <> ";
 
 1193   dictStream << 
"const char *" << clsname << 
"::Class_Name()" << std::endl << 
"{" << std::endl
 
 1194              << 
"   return \"" << fullname << 
"\";"  << std::endl << 
"}" << std::endl << std::endl;
 
 1196   dictStream << 
"//_______________________________________" 
 1197              << 
"_______________________________________" << std::endl;
 
 1198   if (add_template_keyword) dictStream << 
"template <> ";
 
 1199   dictStream << 
"const char *" << clsname << 
"::ImplFileName()"  << std::endl << 
"{" << std::endl
 
 1200              << 
"   return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
 
 1201              << 
"*)nullptr)->GetImplFileName();" << std::endl << 
"}" << std::endl << std::endl
 
 1203              << 
"//_______________________________________" 
 1204              << 
"_______________________________________" << std::endl;
 
 1205   if (add_template_keyword) dictStream << 
"template <> ";
 
 1206   dictStream << 
"int " << clsname << 
"::ImplFileLine()" << std::endl << 
"{" << std::endl
 
 1207              << 
"   return ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
 
 1208              << 
"*)nullptr)->GetImplFileLine();" << std::endl << 
"}" << std::endl << std::endl
 
 1210              << 
"//_______________________________________" 
 1211              << 
"_______________________________________" << std::endl;
 
 1212   if (add_template_keyword) dictStream << 
"template <> ";
 
 1213   dictStream << 
"TClass *" << clsname << 
"::Dictionary()" << std::endl << 
"{" << std::endl;
 
 1217      dictStream << 
"   gInterpreter->AutoLoad(\"" << fullname << 
"\");\n";
 
 1218   dictStream    << 
"   fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::" << fullname
 
 1219                 << 
"*)nullptr)->GetClass();" << std::endl
 
 1220                 << 
"   return fgIsA;\n" 
 1221                 << 
"}" << std::endl << std::endl
 
 1223                 << 
"//_______________________________________" 
 1224                 << 
"_______________________________________" << std::endl;
 
 1225   if (add_template_keyword) dictStream << 
"template <> ";
 
 1226   dictStream << 
"TClass *" << clsname << 
"::Class()" << std::endl << 
"{" << std::endl;
 
 1228      dictStream << 
"   Dictionary();\n";
 
 1230      dictStream << 
"   if (!fgIsA.load()) { R__LOCKGUARD(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
 
 1231      dictStream << fullname << 
"*)nullptr)->GetClass(); }" << std::endl;
 
 1233   dictStream    << 
"   return fgIsA;" << std::endl
 
 1234                 << 
"}" << std::endl << std::endl;
 
 1236   while (enclSpaceNesting) {
 
 1237      dictStream << 
"} // namespace " << nsname << std::endl;
 
 1246                        cling::Interpreter &interp,
 
 1247                        std::ostream &dictStream)
 
 1249   if (cl->isAnonymousNamespace()) {
 
 1261   if (classname != 
"ROOT") {
 
 1265   dictStream << 
"   namespace ROOTDict {" << std::endl;
 
 1268   dictStream << 
"      inline ::ROOT::TGenericClassInfo *GenerateInitInstance();" << std::endl;
 
 1272      dictStream << 
"      static TClass *" << mappedname.c_str() << 
"_Dictionary();" << std::endl;
 
 1273   dictStream << std::endl
 
 1275              << 
"      // Function generating the singleton type initializer" << std::endl
 
 1278              << 
"      inline ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
 
 1279              << 
"      {" << std::endl
 
 1281              << 
"      ::ROOT::TGenericClassInfo *GenerateInitInstance()" << std::endl
 
 1282              << 
"      {" << std::endl
 
 1285              << 
"         static ::ROOT::TGenericClassInfo " << std::endl
 
 1287              << 
"            instance(\"" << classname.c_str() << 
"\", ";
 
 1290      dictStream << 
"::" << classname.c_str() << 
"::Class_Version(), ";
 
 1292      dictStream << 
"0 /*version*/, ";
 
 1296   for (
unsigned int i = 0; i < filename.length(); i++) {
 
 1297      if (filename[i] == 
'\\') filename[i] = 
'/';
 
 1300              << 
"                     ::ROOT::Internal::DefineBehavior((void*)nullptr,(void*)nullptr)," << std::endl
 
 1304      dictStream << 
"&::" << classname.c_str() << 
"::Dictionary, ";
 
 1306      dictStream << 
"&" << mappedname.c_str() << 
"_Dictionary, ";
 
 1309   dictStream << 0 << 
");" << std::endl
 
 1311              << 
"         return &instance;" << std::endl
 
 1312              << 
"      }" << std::endl
 
 1313              << 
"      // Insure that the inline function is _not_ optimized away by the compiler\n" 
 1314              << 
"      ::ROOT::TGenericClassInfo *(*_R__UNIQUE_DICT_(InitFunctionKeeper))() = &GenerateInitInstance;  " << std::endl
 
 1315              << 
"      // Static variable to force the class initialization" << std::endl
 
 1317              << 
"      static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstance();" 
 1318              << 
" R__UseDummy(_R__UNIQUE_DICT_(Init));" << std::endl;
 
 1321      dictStream <<  std::endl << 
"      // Dictionary for non-ClassDef classes" << std::endl
 
 1322                 << 
"      static TClass *" << mappedname.c_str() << 
"_Dictionary() {" << std::endl
 
 1323                 << 
"         return GenerateInitInstance()->GetClass();" << std::endl
 
 1324                 << 
"      }" << std::endl << std::endl;
 
 1327   dictStream << 
"   }" << std::endl;
 
 1329      dictStream << 
"}" << std::endl;
 
 1331   dictStream <<  std::endl;
 
 1340llvm::StringRef 
GrabIndex(
const clang::FieldDecl &member, 
int printError)
 
 1343   llvm::StringRef where;
 
 1346   if (index.size() == 0 && printError) {
 
 1347      const char *errorstring;
 
 1350            errorstring = 
"is not an integer";
 
 1353            errorstring = 
"has not been defined before the array";
 
 1356            errorstring = 
"is a private member of a parent class";
 
 1359            errorstring = 
"is not known";
 
 1362            errorstring = 
"UNKNOWN ERROR!!!!";
 
 1365      if (where.size() == 0) {
 
 1367                                 member.getParent()->getName().str().c_str(), member.getName().str().c_str());
 
 1370                                 member.getParent()->getName().str().c_str(), member.getName().str().c_str(), where.str().c_str(), errorstring);
 
 1379                   const cling::Interpreter &interp,
 
 1381                   std::ostream &dictStream)
 
 1383   const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
 
 1384   if (clxx == 
nullptr) 
return;
 
 1391   int enclSpaceNesting = 0;
 
 1397   dictStream << 
"//_______________________________________" 
 1398              << 
"_______________________________________" << std::endl;
 
 1399   if (add_template_keyword) dictStream << 
"template <> ";
 
 1400   dictStream << 
"void " << clsname << 
"::Streamer(TBuffer &R__b)"  << std::endl << 
"{" << std::endl
 
 1401              << 
"   // Stream an object of class " << fullname << 
"." << std::endl << std::endl;
 
 1409      int basestreamer = 0;
 
 1410      for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
 
 1414            string base_fullname;
 
 1417            if (strstr(base_fullname.c_str(), 
"::")) {
 
 1419               dictStream << 
"   //This works around a msvc bug and should be harmless on other platforms" << std::endl
 
 1420                          << 
"   typedef " << base_fullname << 
" baseClass" << basestreamer << 
";" << std::endl
 
 1421                          << 
"   baseClass" << basestreamer << 
"::Streamer(R__b);" << std::endl;
 
 1423               dictStream << 
"   " << base_fullname << 
"::Streamer(R__b);" << std::endl;
 
 1428      if (!basestreamer) {
 
 1429         dictStream << 
"   ::Error(\"" << fullname << 
"::Streamer\", \"version id <=0 in ClassDef," 
 1430                    " dummy Streamer() called\"); if (R__b.IsReading()) { }" << std::endl;
 
 1432      dictStream << 
"}" << std::endl << std::endl;
 
 1433      while (enclSpaceNesting) {
 
 1434         dictStream << 
"} // namespace " << nsname.c_str() << std::endl;
 
 1441   string classname = fullname;
 
 1442   if (strstr(fullname.c_str(), 
"::")) {
 
 1444      dictStream << 
"   //This works around a msvc bug and should be harmless on other platforms" << std::endl
 
 1445                 << 
"   typedef ::" << fullname << 
" thisClass;" << std::endl;
 
 1446      classname = 
"thisClass";
 
 1448   for (
int i = 0; i < 2; i++) {
 
 1453         dictStream << 
"   UInt_t R__s, R__c;" << std::endl;
 
 1454         dictStream << 
"   if (R__b.IsReading()) {" << std::endl;
 
 1455         dictStream << 
"      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }" << std::endl;
 
 1457         dictStream << 
"      R__b.CheckByteCount(R__s, R__c, " << classname.c_str() << 
"::IsA());" << std::endl;
 
 1458         dictStream << 
"   } else {" << std::endl;
 
 1459         dictStream << 
"      R__c = R__b.WriteVersion(" << classname.c_str() << 
"::IsA(), kTRUE);" << std::endl;
 
 1464      for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
 
 1468            string base_fullname;
 
 1471            if (strstr(base_fullname.c_str(), 
"::")) {
 
 1473               dictStream << 
"      //This works around a msvc bug and should be harmless on other platforms" << std::endl
 
 1474                          << 
"      typedef " << base_fullname << 
" baseClass" << base << 
";" << std::endl
 
 1475                          << 
"      baseClass" << base << 
"::Streamer(R__b);" << std::endl;
 
 1478               dictStream << 
"      " << base_fullname << 
"::Streamer(R__b);" << std::endl;
 
 1484      for (clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
 
 1489         clang::QualType 
type = field_iter->getType();
 
 1490         std::string type_name = 
type.getAsString(clxx->getASTContext().getPrintingPolicy());
 
 1500         if (strstr(type_name.c_str(), 
"Float16_t")) isFloat16 = 1;
 
 1504         if (strstr(type_name.c_str(), 
"Double32_t")) isDouble32 = 1;
 
 1507         if (strncmp(comment, 
"!", 1)) {
 
 1510            if (underling_type->isFundamentalType() || underling_type->isEnumeralType()) {
 
 1511               if (
type.getTypePtr()->isConstantArrayType() &&
 
 1512                     type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
 
 1513                  const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
 
 1517                     dictStream << 
"      int R__i;" << std::endl;
 
 1520                  dictStream << 
"      for (R__i = 0; R__i < " << s << 
"; R__i++)" << std::endl;
 
 1522                     ROOT::TMetaUtils::Error(
nullptr, 
"*** Datamember %s::%s: array of pointers to fundamental type (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
 
 1523                     dictStream << 
"         ;//R__b.ReadArray(" << field_iter->getName().str() << 
");" << std::endl;
 
 1525                     dictStream << 
"         ;//R__b.WriteArray(" << field_iter->getName().str() << 
", __COUNTER__);" << std::endl;
 
 1527               } 
else if (
type.getTypePtr()->isPointerType()) {
 
 1528                  llvm::StringRef indexvar = 
GrabIndex(**field_iter, i == 0);
 
 1529                  if (indexvar.size() == 0) {
 
 1531                        ROOT::TMetaUtils::Error(
nullptr, 
"*** Datamember %s::%s: pointer to fundamental type (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
 
 1532                        dictStream << 
"      //R__b.ReadArray(" << field_iter->getName().str() << 
");" << std::endl;
 
 1534                        dictStream << 
"      //R__b.WriteArray(" << field_iter->getName().str() << 
", __COUNTER__);" << std::endl;
 
 1538                        dictStream << 
"      delete [] " << field_iter->getName().str() << 
";" << std::endl
 
 1543                                      << 
"," << indexvar.str() << 
");" << std::endl;
 
 1544                        } 
else if (isDouble32) {
 
 1546                                      << 
"," << indexvar.str() << 
");" << std::endl;
 
 1549                                      << 
"," << indexvar.str() << 
");" << std::endl;
 
 1553                           dictStream << 
"      R__b.WriteFastArrayFloat16(" 
 1554                                      << field_iter->getName().str() << 
"," << indexvar.str() << 
");" << std::endl;
 
 1555                        } 
else if (isDouble32) {
 
 1556                           dictStream << 
"      R__b.WriteFastArrayDouble32(" 
 1557                                      << field_iter->getName().str() << 
"," << indexvar.str() << 
");" << std::endl;
 
 1559                           dictStream << 
"      R__b.WriteFastArray(" 
 1560                                      << field_iter->getName().str() << 
"," << indexvar.str() << 
");" << std::endl;
 
 1564               } 
else if (
type.getTypePtr()->isArrayType()) {
 
 1566                     if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) { 
 
 1567                        if (underling_type->isEnumeralType())
 
 1568                           dictStream << 
"      R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1572                                         << 
"*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1573                           } 
else if (isDouble32) {
 
 1575                                         << 
"*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1578                                         << 
"*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1582                        if (underling_type->isEnumeralType()) {
 
 1583                           dictStream << 
"      R__b.ReadStaticArray((Int_t*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1586                              dictStream << 
"      R__b.ReadStaticArrayFloat16(" << field_iter->getName().str() << 
");" << std::endl;
 
 1587                           } 
else if (isDouble32) {
 
 1588                              dictStream << 
"      R__b.ReadStaticArrayDouble32(" << field_iter->getName().str() << 
");" << std::endl;
 
 1591                                         << 
"*)" << field_iter->getName().str() << 
");" << std::endl;
 
 1596                     const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
 
 1599                     if (
type.getTypePtr()->getArrayElementTypeNoTypeQual()->isArrayType()) {
 
 1600                        if (underling_type->isEnumeralType())
 
 1601                           dictStream << 
"      R__b.WriteArray((Int_t*)" << field_iter->getName().str() << 
", " 
 1602                                      << s << 
");" << std::endl;
 
 1603                        else if (isFloat16) {
 
 1605                                      << 
"*)" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1606                        } 
else if (isDouble32) {
 
 1608                                      << 
"*)" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1611                                      << 
"*)" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1614                        if (underling_type->isEnumeralType())
 
 1615                           dictStream << 
"      R__b.WriteArray((Int_t*)" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1616                        else if (isFloat16) {
 
 1617                           dictStream << 
"      R__b.WriteArrayFloat16(" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1618                        } 
else if (isDouble32) {
 
 1619                           dictStream << 
"      R__b.WriteArrayDouble32(" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1621                           dictStream << 
"      R__b.WriteArray(" << field_iter->getName().str() << 
", " << s << 
");" << std::endl;
 
 1625               } 
else if (underling_type->isEnumeralType()) {
 
 1627                     dictStream << 
"      void *ptr_" << field_iter->getName().str() << 
" = (void*)&" << field_iter->getName().str() << 
";\n";
 
 1628                     dictStream << 
"      R__b >> *reinterpret_cast<Int_t*>(ptr_" << field_iter->getName().str() << 
");" << std::endl;
 
 1630                     dictStream << 
"      R__b << (Int_t)" << field_iter->getName().str() << 
";" << std::endl;
 
 1635                                   << 
"=Float16_t(R_Dummy);}" << std::endl;
 
 1638                  } 
else if (isDouble32) {
 
 1641                                   << 
"=Double32_t(R_Dummy);}" << std::endl;
 
 1663               if (
type.getTypePtr()->isConstantArrayType() &&
 
 1664                     type.getTypePtr()->getArrayElementTypeNoTypeQual()->isPointerType()) {
 
 1665                  const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr());
 
 1669                     dictStream << 
"      int R__i;" << std::endl;
 
 1672                  dictStream << 
"      for (R__i = 0; R__i < " << s << 
"; R__i++)" << std::endl;
 
 1677                        dictStream << 
"         R__b << (TObject*)" << field_iter->getName().str();
 
 1682                  dictStream << 
"[R__i];" << std::endl;
 
 1683               } 
else if (
type.getTypePtr()->isPointerType()) {
 
 1691                        ROOT::TMetaUtils::Error(
nullptr, 
"*** Datamember %s::%s: pointer to pointer (need manual intervention)\n", fullname.c_str(), field_iter->getName().str().c_str());
 
 1692                        dictStream << 
"      //R__b.ReadArray(" << field_iter->getName().str() << 
");" << std::endl;
 
 1694                        dictStream << 
"      //R__b.WriteArray(" << field_iter->getName().str() << 
", __COUNTER__);";
 
 1698                        dictStream << 
"      " << field_iter->getName().str() << 
"->Streamer(R__b);" << std::endl;
 
 1712                              dictStream << 
"      R__b << (TObject*)" << field_iter->getName().str() << 
";" << std::endl;
 
 1718               } 
else if (
const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
type.getTypePtr())) {
 
 1722                     dictStream << 
"      int R__i;" << std::endl;
 
 1725                  dictStream << 
"      for (R__i = 0; R__i < " << s << 
"; R__i++)" << std::endl;
 
 1726                  std::string mTypeNameStr;
 
 1728                  const char *mTypeName = mTypeNameStr.c_str();
 
 1729                  const char *constwd = 
"const ";
 
 1730                  if (strncmp(constwd, mTypeName, strlen(constwd)) == 0) {
 
 1731                     mTypeName += strlen(constwd);
 
 1732                     dictStream << 
"         const_cast< " << mTypeName << 
" &>(" << field_iter->getName().str();
 
 1734                     dictStream << 
"[R__i]).Streamer(R__b);" << std::endl;
 
 1738                     dictStream << 
"[R__i].Streamer(R__b);" << std::endl;
 
 1744                     dictStream << 
"      R__b.StreamObject(&(" << field_iter->getName().str() << 
"),typeid(" 
 1745                                << field_iter->getName().str() << 
"));" << std::endl;               
 
 1756   dictStream << 
"      R__b.SetByteCount(R__c, kTRUE);" << std::endl
 
 1757              << 
"   }" << std::endl
 
 1758              << 
"}" << std::endl << std::endl;
 
 1760   while (enclSpaceNesting) {
 
 1761      dictStream << 
"} // namespace " << nsname.c_str() << std::endl;
 
 1769                       const cling::Interpreter &interp,
 
 1771                       std::ostream &dictStream)
 
 1775   const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
 
 1776   if (clxx == 
nullptr) 
return;
 
 1781   for (clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
 
 1793   int enclSpaceNesting = 0;
 
 1799   dictStream << 
"//_______________________________________" 
 1800              << 
"_______________________________________" << std::endl;
 
 1801   if (add_template_keyword) dictStream << 
"template <> ";
 
 1802   dictStream << 
"void " << clsname << 
"::Streamer(TBuffer &R__b)" << std::endl
 
 1804              << 
"   // Stream an object of class " << fullname << 
"." << std::endl << std::endl
 
 1805              << 
"   if (R__b.IsReading()) {" << std::endl
 
 1806              << 
"      R__b.ReadClassBuffer(" << fullname << 
"::Class(),this);" << std::endl
 
 1807              << 
"   } else {" << std::endl
 
 1808              << 
"      R__b.WriteClassBuffer(" << fullname << 
"::Class(),this);" << std::endl
 
 1809              << 
"   }" << std::endl
 
 1810              << 
"}" << std::endl << std::endl;
 
 1812   while (enclSpaceNesting) {
 
 1813      dictStream << 
"} // namespace " << nsname << std::endl;
 
 1821                       const cling::Interpreter &interp,
 
 1823                       std::ostream &dictStream,
 
 1824                       bool isAutoStreamer)
 
 1826   if (isAutoStreamer) {
 
 1836                     std::string &code_for_parser)
 
 1838   code_for_parser += 
"#ifdef __CINT__\n\n";
 
 1839   code_for_parser += 
"#pragma link off all globals;\n";
 
 1840   code_for_parser += 
"#pragma link off all classes;\n";
 
 1841   code_for_parser += 
"#pragma link off all functions;\n\n";
 
 1843   for (std::string& arg : InputFiles) {
 
 1845      int nostr = 0, noinp = 0, bcnt = 0, 
l = arg.length() - 1;
 
 1846      for (
int j = 0; j < 3; j++) {
 
 1847         if (arg[
l] == 
'-') {
 
 1852         if (arg[
l] == 
'!') {
 
 1857         if (arg[
l] == 
'+') {
 
 1863      if (nostr || noinp) {
 
 1865         if (nostr) strlcat(trail, 
"-", 3);
 
 1866         if (noinp) strlcat(trail, 
"!", 3);
 
 1869         strlcpy(trail, 
"+", 3);
 
 1873      llvm::SmallString<256> filestem = llvm::sys::path::filename(arg);
 
 1874      llvm::sys::path::replace_extension(filestem, 
"");
 
 1876      code_for_parser += 
"#pragma link C++ class ";
 
 1877      code_for_parser += filestem.str().str();
 
 1878      if (nostr || noinp || bcnt)
 
 1879         code_for_parser += trail;
 
 1880      code_for_parser += 
";\n";
 
 1883   code_for_parser += 
"\n#endif\n";
 
 1891bool Which(cling::Interpreter &interp, 
const char *fname, 
string &pname)
 
 1896   static const char *fopenopts = 
"rb";
 
 1898   static const char *fopenopts = 
"r";
 
 1902   fp = fopen(pname.c_str(), fopenopts);
 
 1908   llvm::SmallVector<std::string, 10> includePaths;
 
 1910   interp.GetIncludePaths(includePaths, 
false, 
false);
 
 1912   const size_t nPaths = includePaths.size();
 
 1913   for (
size_t i = 0; i < nPaths; i += 1 ) {
 
 1917      fp = fopen(pname.c_str(), fopenopts);
 
 1939   const char *inc = strstr(original, 
"\\inc\\");
 
 1941      inc = strstr(original, 
"/inc/");
 
 1942   if (inc && strlen(inc) > 5)
 
 1962                                   cling::Interpreter &interp,
 
 1965   std::ostringstream out;
 
 1970      if (interp.declare(out.str()) != cling::Interpreter::kSuccess) {
 
 1971         const std::string &hdrName
 
 1989static bool WriteAST(llvm::StringRef fileName, clang::CompilerInstance *compilerInstance,
 
 1990                     llvm::StringRef iSysRoot,
 
 1991                     clang::Module *module = 
nullptr)
 
 1994   llvm::SmallVector<char, 128> buffer;
 
 1995   llvm::BitstreamWriter stream(buffer);
 
 1996   clang::ASTWriter 
writer(stream, buffer, compilerInstance->getModuleCache(), {});
 
 1997   std::unique_ptr<llvm::raw_ostream> out =
 
 1998      compilerInstance->createOutputFile(fileName, 
true,
 
 2007   compilerInstance->getFrontendOpts().RelocatablePCH = 
true;
 
 2009   writer.WriteAST(compilerInstance->getSema(), fileName, module, iSysRoot);
 
 2012   out->write(&buffer.front(), buffer.size());
 
 2024                            const std::string ¤tDirectory)
 
 2026   assert(modGen.
IsPCH() && 
"modGen must be in PCH mode");
 
 2028   std::string iSysRoot(
"/DUMMY_SYSROOT/include/");
 
 2036static bool IncludeHeaders(
const std::vector<std::string> &headers, cling::Interpreter &interpreter)
 
 2039   if (headers.empty())
 
 2043   std::stringstream includes;
 
 2044   for (
const std::string &header : headers) {
 
 2045      includes << 
"#include \"" << header << 
"\"\n";
 
 2047   std::string includeListStr = includes.str();
 
 2048   auto result = interpreter.declare(includeListStr);
 
 2049   return result == cling::Interpreter::CompilationResult::kSuccess;
 
 2057   char platformDefines[64] = {0};
 
 2058#ifdef __INTEL_COMPILER 
 2059   snprintf(platformDefines, 64, 
"-DG__INTEL_COMPILER=%ld", (
long)__INTEL_COMPILER);
 
 2060   clingArgs.push_back(platformDefines);
 
 2063   snprintf(platformDefines, 64, 
"-DG__xlC=%ld", (
long)__xlC__);
 
 2064   clingArgs.push_back(platformDefines);
 
 2067   snprintf(platformDefines, 64, 
"-DG__GNUC=%ld", (
long)__GNUC__);
 
 2068   snprintf(platformDefines, 64, 
"-DG__GNUC_VER=%ld", (
long)__GNUC__ * 1000 + __GNUC_MINOR__);
 
 2069   clingArgs.push_back(platformDefines);
 
 2071#ifdef __GNUC_MINOR__ 
 2072   snprintf(platformDefines, 64, 
"-DG__GNUC_MINOR=%ld", (
long)__GNUC_MINOR__);
 
 2073   clingArgs.push_back(platformDefines);
 
 2076   snprintf(platformDefines, 64, 
"-DG__HP_aCC=%ld", (
long)__HP_aCC);
 
 2077   clingArgs.push_back(platformDefines);
 
 2080   snprintf(platformDefines, 64, 
"-DG__sun=%ld", (
long)__sun);
 
 2081   clingArgs.push_back(platformDefines);
 
 2084   snprintf(platformDefines, 64, 
"-DG__SUNPRO_CC=%ld", (
long)__SUNPRO_CC);
 
 2085   clingArgs.push_back(platformDefines);
 
 2087#ifdef _STLPORT_VERSION 
 2089   snprintf(platformDefines, 64, 
"-DG__STLPORT_VERSION=%ld", (
long)_STLPORT_VERSION);
 
 2090   clingArgs.push_back(platformDefines);
 
 2093   snprintf(platformDefines, 64, 
"-DG__ia64=%ld", (
long)__ia64__);
 
 2094   clingArgs.push_back(platformDefines);
 
 2097   snprintf(platformDefines, 64, 
"-DG__x86_64=%ld", (
long)__x86_64__);
 
 2098   clingArgs.push_back(platformDefines);
 
 2101   snprintf(platformDefines, 64, 
"-DG__i386=%ld", (
long)__i386__);
 
 2102   clingArgs.push_back(platformDefines);
 
 2105   snprintf(platformDefines, 64, 
"-DG__arm=%ld", (
long)__arm__);
 
 2106   clingArgs.push_back(platformDefines);
 
 2109   snprintf(platformDefines, 64, 
"-DG__WIN32=%ld", (
long)_WIN32);
 
 2110   clingArgs.push_back(platformDefines);
 
 2113   snprintf(platformDefines, 64, 
"-DG__WIN32=%ld", (
long)WIN32);
 
 2114   clingArgs.push_back(platformDefines);
 
 2118   snprintf(platformDefines, 64, 
"-DG__WIN64=%ld", (
long)_WIN64);
 
 2119   clingArgs.push_back(platformDefines);
 
 2122   snprintf(platformDefines, 64, 
"-DG__MSC_VER=%ld", (
long)_MSC_VER);
 
 2123   clingArgs.push_back(platformDefines);
 
 2124   snprintf(platformDefines, 64, 
"-DG__VISUAL=%ld", (
long)_MSC_VER);
 
 2125   clingArgs.push_back(platformDefines);
 
 2134   return llvm::sys::path::filename(path);
 
 2144   if (std::string::npos != pos) {
 
 2145      dirname.assign(path.begin(), path.begin() + pos + 1);
 
 2156   std::string dictLocation;
 
 2158   return !dictLocation.empty();
 
 2164                        std::string &rootmapLibName)
 
 2168   if (rootmapFileName.empty()) {
 
 2170      rootmapFileName = rootmapLibName.substr(0, libExtensionPos) + 
".rootmap";
 
 2171      size_t libCleanNamePos = rootmapLibName.find_last_of(
gPathSeparator) + 1;
 
 2172      rootmapLibName = rootmapLibName.substr(libCleanNamePos, std::string::npos);
 
 2174                             rootmapLibName.c_str(),
 
 2175                             rootmapFileName.c_str());
 
 2184                                       std::string &ctxtName,
 
 2185                                       const cling::Interpreter &interpreter,
 
 2186                                       bool treatParent = 
true)
 
 2188   const clang::DeclContext *outerCtxt = treatParent ? theContext.getParent() : &theContext;
 
 2190   if (!outerCtxt) 
return;
 
 2192   if (
const clang::RecordDecl *thisRcdDecl = llvm::dyn_cast<clang::RecordDecl>(outerCtxt)) {
 
 2202      std::string &ctxtName,
 
 2203      const cling::Interpreter &interpreter)
 
 2205   const clang::DeclContext *theContext = theDecl.getDeclContext();
 
 2213                        const cling::Interpreter &interp)
 
 2215   if (!decls.empty()) {
 
 2216      std::string autoLoadKey;
 
 2217      for (
auto & 
d : decls) {
 
 2221         if (autoLoadKey.empty()) {
 
 2222            names.push_back(
d->getQualifiedNameAsString());
 
 2240                         const std::string &rootmapLibName,
 
 2241                         const std::list<std::string> &classesDefsList,
 
 2242                         const std::list<std::string> &classesNames,
 
 2243                         const std::list<std::string> &nsNames,
 
 2244                         const std::list<std::string> &tdNames,
 
 2245                         const std::list<std::string> &enNames,
 
 2246                         const std::list<std::string> &varNames,
 
 2248                         const std::unordered_set<std::string> headersToIgnore)
 
 2251   std::ofstream rootmapFile(rootmapFileName.c_str());
 
 2259   std::unordered_set<std::string> classesKeys;
 
 2263   if (!classesNames.empty() || !nsNames.empty() || !tdNames.empty() ||
 
 2264      !enNames.empty() || !varNames.empty()) {
 
 2267      if (!classesDefsList.empty()) {
 
 2268         rootmapFile << 
"{ decls }\n";
 
 2269         for (
auto & classDef : classesDefsList) {
 
 2270            rootmapFile << classDef << std::endl;
 
 2272         rootmapFile << 
"\n";
 
 2274      rootmapFile << 
"[ " << rootmapLibName << 
" ]\n";
 
 2277      if (!classesNames.empty()) {
 
 2278         rootmapFile << 
"# List of selected classes\n";
 
 2279         for (
auto & className : classesNames) {
 
 2280            rootmapFile << 
"class " << className << std::endl;
 
 2281            classesKeys.insert(className);
 
 2284         std::unordered_set<std::string> treatedHeaders;
 
 2285         for (
auto & className : classesNames) {
 
 2287            if (className.find(
"<") != std::string::npos) 
continue;
 
 2288            if (headersClassesMap.count(className)) {
 
 2289               auto &headers = headersClassesMap.at(className);
 
 2290               if (!headers.empty()){
 
 2291                  auto &header = headers.front();
 
 2292                  if (treatedHeaders.insert(header).second &&
 
 2293                        headersToIgnore.find(header) == headersToIgnore.end() &&
 
 2295                        rootmapFile << 
"header " << header << std::endl;
 
 2303      if (!nsNames.empty()) {
 
 2304         rootmapFile << 
"# List of selected namespaces\n";
 
 2305         for (
auto & nsName : nsNames) {
 
 2306            rootmapFile << 
"namespace " << nsName << std::endl;
 
 2311      if (!tdNames.empty()) {
 
 2312         rootmapFile << 
"# List of selected typedefs and outer classes\n";
 
 2313         for (
const auto & autoloadKey : tdNames)
 
 2314            if (classesKeys.insert(autoloadKey).second)
 
 2315               rootmapFile << 
"typedef " << autoloadKey << std::endl;
 
 2320      if (!enNames.empty()){
 
 2321         rootmapFile << 
"# List of selected enums and outer classes\n";
 
 2322         for (
const auto & autoloadKey : enNames)
 
 2323            if (classesKeys.insert(autoloadKey).second)
 
 2324               rootmapFile << 
"enum " << autoloadKey << std::endl;
 
 2328      if (!varNames.empty()){
 
 2329         rootmapFile << 
"# List of selected vars\n";
 
 2330         for (
const auto & autoloadKey : varNames)
 
 2331            if (classesKeys.insert(autoloadKey).second)
 
 2332               rootmapFile << 
"var " << autoloadKey << std::endl;
 
 2346   auto nsPattern = 
'{'; 
auto nsPatternLength = 1;
 
 2347   auto foundNsPos = 
line.find_last_of(nsPattern);
 
 2348   if (foundNsPos == std::string::npos) 
return {
"",
""};
 
 2349   foundNsPos+=nsPatternLength;
 
 2350   auto extNs = 
line.substr(0,foundNsPos);
 
 2352   auto nsEndPattern = 
'}';
 
 2353   auto foundEndNsPos = 
line.find(nsEndPattern);
 
 2354   auto contained = 
line.substr(foundNsPos, foundEndNsPos-foundNsPos);
 
 2356   return {extNs, contained};
 
 2372   std::map<std::string, std::string> nsEntitiesMap;
 
 2373   std::list<std::string> optFwdDeclList;
 
 2374   for (
auto const & fwdDecl : fwdDeclarationsList){
 
 2377      if (extNsAndEntities.first.empty()) {
 
 2379         optFwdDeclList.push_front(fwdDecl);
 
 2381      auto currentVal = nsEntitiesMap[extNsAndEntities.first];
 
 2382      nsEntitiesMap[extNsAndEntities.first] = currentVal +=extNsAndEntities.second;
 
 2386   std::string optFwdDecl;
 
 2387   for (
auto const & extNsAndEntities : nsEntitiesMap) {
 
 2388      optFwdDecl = extNsAndEntities.first;
 
 2389      optFwdDecl += extNsAndEntities.second;
 
 2390      for (
int i = 0; i < std::count(optFwdDecl.begin(), optFwdDecl.end(), 
'{'); ++i ){
 
 2393      optFwdDeclList.push_front(optFwdDecl);
 
 2396   return optFwdDeclList;
 
 2404                                std::list<std::string> &el_list,
 
 2405                                std::unordered_set<std::string> &el_set)
 
 2407   std::stringstream elStream(el);
 
 2410   while (getline(elStream, tmp, 
'\n')) {
 
 2412      if (el_set.insert(tmp).second && !tmp.empty()) {
 
 2413         el_list.push_back(tmp);
 
 2424      std::list<std::string> &classesList,
 
 2425      std::list<std::string> &classesListForRootmap,
 
 2426      std::list<std::string> &fwdDeclarationsList,
 
 2427      const cling::Interpreter &interpreter)
 
 2435   std::unordered_set<std::string> classesSet;
 
 2436   std::unordered_set<std::string> outerMostClassesSet;
 
 2438   std::string attrName, attrValue;
 
 2439   bool isClassSelected;
 
 2440   std::unordered_set<std::string> availableFwdDecls;
 
 2441   std::string fwdDeclaration;
 
 2443      fwdDeclaration = 
"";
 
 2449      fwdDeclaration = 
"";
 
 2456      isClassSelected = 
true;
 
 2457      const clang::RecordDecl *rDecl = selClass.GetRecordDecl();
 
 2458      std::string normalizedName;
 
 2459      normalizedName = selClass.GetNormalizedName();
 
 2460      if (!normalizedName.empty() &&
 
 2461            !classesSet.insert(normalizedName).second &&
 
 2462            outerMostClassesSet.count(normalizedName) == 0) {
 
 2463         std::cerr << 
"FATAL: A class with normalized name " << normalizedName
 
 2464                   << 
" was already selected. This means that two different instances of" 
 2465                   << 
" clang::RecordDecl had the same name, which is not possible." 
 2466                   << 
" This can be a hint of a serious problem in the class selection." 
 2467                   << 
" In addition, the generated dictionary would not even compile.\n";
 
 2470      classesList.push_back(normalizedName);
 
 2473      const char *reqName(selClass.GetRequestedName());
 
 2476      fwdDeclaration = 
"";
 
 2481      if (llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl)) {
 
 2482         fwdDeclaration = 
"";
 
 2485            std::string fwdDeclarationTemplateSpec;
 
 2487            fwdDeclaration += 
'\n' + fwdDeclarationTemplateSpec;
 
 2495      for (
auto ait = rDecl->attr_begin(); ait != rDecl->attr_end(); ++ait) {
 
 2497               attrName == 
"rootmap" &&
 
 2498               attrValue == 
"false") {
 
 2499            attrName = attrValue = 
"";
 
 2500            isClassSelected = 
false;
 
 2504      if (isClassSelected) {
 
 2520         std::string outerMostClassName;
 
 2522         if (!outerMostClassName.empty() &&
 
 2523             !llvm::isa<clang::ClassTemplateSpecializationDecl>(rDecl) &&
 
 2524             classesSet.insert(outerMostClassName).second &&
 
 2525             outerMostClassesSet.insert(outerMostClassName).second) {
 
 2526            classesListForRootmap.push_back(outerMostClassName);
 
 2528            classesListForRootmap.push_back(normalizedName);
 
 2529            if (reqName && reqName[0] && reqName != normalizedName) {
 
 2530               classesListForRootmap.push_back(reqName);
 
 2535            std::string demangledName = selClass.GetDemangledTypeInfo();
 
 2536            if (!demangledName.empty()) {
 
 2541               if (demangledName != normalizedName && (!reqName || demangledName != reqName)) {
 
 2543                  classesListForRootmap.push_back(demangledName);
 
 2549   classesListForRootmap.sort();
 
 2562   for (RScanner::NamespaceColl_t::const_iterator selNsIter = scan.
fSelectedNamespaces.begin();
 
 2577      if (clang::CXXRecordDecl *CXXRD =
 
 2578               llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
 
 2590      if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
 
 2593      const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
 
 2596                                 "Interactivity only dictionaries are not supported for classes with ClassDef\n");
 
 2612   if (interp.parseForModule(
"#include \"TStreamerInfo.h\"\n" 
 2613                             "#include \"TFile.h\"\n" 
 2614                             "#include \"TObjArray.h\"\n" 
 2615                             "#include \"TVirtualArray.h\"\n" 
 2616                             "#include \"TStreamerElement.h\"\n" 
 2617                             "#include \"TProtoClass.h\"\n" 
 2618                             "#include \"TBaseClass.h\"\n" 
 2619                             "#include \"TListOfDataMembers.h\"\n" 
 2620                             "#include \"TListOfEnums.h\"\n" 
 2621                             "#include \"TListOfEnumsWithLock.h\"\n" 
 2622                             "#include \"TDataMember.h\"\n" 
 2623                             "#include \"TEnum.h\"\n" 
 2624                             "#include \"TEnumConstant.h\"\n" 
 2625                             "#include \"TDictAttributeMap.h\"\n" 
 2626                             "#include \"TMessageHandler.h\"\n" 
 2627                             "#include \"TArray.h\"\n" 
 2628                             "#include \"TRefArray.h\"\n" 
 2629                             "#include \"root_std_complex.h\"\n")
 
 2630       != cling::Interpreter::kSuccess)
 
 2641                     cling::Interpreter &interp,
 
 2646                     bool writeEmptyRootPCM)
 
 2650   bool needsCollectionProxy = 
false;
 
 2672      auto nsName = ns.GetNamespaceDecl()->getQualifiedNameAsString();
 
 2673      if (nsName.find(
"(anonymous)") == std::string::npos)
 
 2678      if (!selClass.GetRecordDecl()->isCompleteDefinition()) {
 
 2682      if (selClass.RequestOnlyTClass()) {
 
 2690      if (clang::CXXRecordDecl *CXXRD =
 
 2691               llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::RecordDecl *
>(selClass.GetRecordDecl()))) {
 
 2695      const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
 
 2703         } 
else if (CRD->getName() == 
"RVec") {
 
 2704            static const clang::DeclContext *vecOpsDC = 
nullptr;
 
 2706               vecOpsDC = llvm::dyn_cast<clang::DeclContext>(
 
 2707                  interp.getLookupHelper().findScope(
"ROOT::VecOps", cling::LookupHelper::NoDiagnostics));
 
 2708            if (vecOpsDC && vecOpsDC->Equals(CRD->getDeclContext())) {
 
 2716                                                needsCollectionProxy);
 
 2731      if (!selClass.GetRecordDecl()->isCompleteDefinition() || selClass.RequestOnlyTClass()) {
 
 2735      const clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
 
 2747      if (!selClass.GetRecordDecl()->isCompleteDefinition() || !selClass.RequestOnlyTClass()) {
 
 2751      const clang::CXXRecordDecl *CRD = llvm::dyn_cast<clang::CXXRecordDecl>(selClass.GetRecordDecl());
 
 2756                                             needsCollectionProxy);
 
 2785      if (finRetCode != 0) 
return finRetCode;
 
 2795   dictStream  << 
"// Do NOT change. Changes will be lost next time file is generated\n\n" 
 2796               << 
"#define R__DICTIONARY_FILENAME " << main_dictname << std::endl
 
 2799               << 
"#define R__NO_DEPRECATION" << std::endl
 
 2804               << 
"\n/*******************************************************************/\n" 
 2805               << 
"#include <stddef.h>\n" 
 2806               << 
"#include <stdio.h>\n" 
 2807               << 
"#include <stdlib.h>\n" 
 2808               << 
"#include <string.h>\n" 
 2809               << 
"#include <assert.h>\n" 
 2810               << 
"#define G__DICTIONARY\n" 
 2811               << 
"#include \"RConfig.h\"\n" 
 2812               << 
"#include \"TClass.h\"\n" 
 2813               << 
"#include \"TDictAttributeMap.h\"\n" 
 2814               << 
"#include \"TInterpreter.h\"\n" 
 2815               << 
"#include \"TROOT.h\"\n" 
 2816               << 
"#include \"TBuffer.h\"\n" 
 2817               << 
"#include \"TMemberInspector.h\"\n" 
 2818               << 
"#include \"TInterpreter.h\"\n" 
 2819               << 
"#include \"TVirtualMutex.h\"\n" 
 2820               << 
"#include \"TError.h\"\n\n" 
 2821               << 
"#ifndef G__ROOT\n" 
 2822               << 
"#define G__ROOT\n" 
 2824               << 
"#include \"RtypesImp.h\"\n" 
 2825               << 
"#include \"TIsAProxy.h\"\n" 
 2826               << 
"#include \"TFileMergeInfo.h\"\n" 
 2827               << 
"#include <algorithm>\n" 
 2828               << 
"#include \"TCollectionProxyInfo.h\"\n" 
 2829               << 
"/*******************************************************************/\n\n" 
 2830               << 
"#include \"TDataMember.h\"\n\n"; 
 
 2837   dictStream  << 
"// The generated code does not explicitly qualify STL entities\n" 
 2838               << 
"namespace std {} using namespace std;\n\n";
 
 2844                               const std::string &includeForSource,
 
 2845                               const std::string &extraIncludes)
 
 2847   dictStream << 
"// Header files passed as explicit arguments\n" 
 2848              << includeForSource << std::endl
 
 2849              << 
"// Header files passed via #pragma extra_include\n" 
 2850              << extraIncludes << std::endl;
 
 2856#if defined(R__IOSSIM) || defined(R__IOS) 
 2881      return filename + 
"_tmp_" + std::to_string(getpid());
 
 2888      if (nameStr.empty()) 
return;
 
 2890      std::string tmpNameStr(getTmpFileName(nameStr));
 
 2893      const char *
name(nameStr.c_str());
 
 2894      const char *tmpName(tmpNameStr.c_str());
 
 2896      m_names.push_back(nameStr);
 
 2897      m_tempNames.push_back(tmpNameStr);
 
 2901      if (0 == std::rename(
name , tmpName)) {
 
 2906      nameStr = tmpNameStr;
 
 2917      for (
unsigned int i = 0; i < m_size; ++i) {
 
 2918         const char *tmpName = m_tempNames[i].c_str();
 
 2920         std::ifstream ifile(tmpName);
 
 2925         if (ifile.is_open())
 
 2927         if (0 != std::remove(tmpName)) {
 
 2940      for (
unsigned int i = 0; i < m_size; ++i) {
 
 2941         const char *tmpName = m_tempNames[i].c_str();
 
 2942         const char *
name = m_names[i].c_str();
 
 2944         std::ifstream ifile(tmpName);
 
 2949         if (ifile.is_open())
 
 2955         if (0 != std::rename(tmpName , 
name)) {
 
 2956            if (llvm::sys::fs::copy_file(tmpName , 
name)) {
 
 2957               llvm::sys::fs::remove(tmpName);
 
 2961         if (0 != std::rename(tmpName , 
name)) {
 
 2973      size_t i = std::distance(m_tempNames.begin(),
 
 2974                               find(m_tempNames.begin(), m_tempNames.end(), tmpFileName));
 
 2975      if (i == m_tempNames.size()) 
return m_emptyString;
 
 2982      std::cout << 
"Restoring files in temporary file catalog:\n";
 
 2983      for (
unsigned int i = 0; i < m_size; ++i) {
 
 2984         std::cout <<  m_tempNames[i] << 
" --> " << m_names[i] << std::endl;
 
 3001   std::string splitDictName(tmpCatalog.
getFileName(dictpathname));
 
 3002   const size_t dotPos = splitDictName.find_last_of(
".");
 
 3003   splitDictName.insert(dotPos, 
"_classdef");
 
 3005   return new std::ofstream(splitDictName.c_str());
 
 3014                           std::list<std::string> &diagnosticPragmas)
 
 3016   static const std::string pattern(
"-Wno-");
 
 3018   if (arg.find(pattern) != 0)
 
 3020   if (arg == 
"-Wno-noexcept-type") {
 
 3027   diagnosticPragmas.push_back(arg);
 
 3033                                        cling::Interpreter &interp)
 
 3036   std::string fwdDecl;
 
 3037   std::string initStr(
"{");
 
 3039   for (
auto & strigNargsToKeepPair : fwdDeclnArgsToSkipColl) {
 
 3040      auto &clTemplDecl = *strigNargsToKeepPair.first;
 
 3041      FwdDeclFromTmplDecl(clTemplDecl , interp, fwdDecl);
 
 3044                 + std::to_string(strigNargsToKeepPair.second)
 
 3047   if (!fwdDeclnArgsToSkipColl.empty())
 
 3058   if (qt.isNull()) 
return qt;
 
 3059   clang::QualType thisQt(qt);
 
 3060   while (thisQt->isPointerType() ||
 
 3061          thisQt->isReferenceType()) {
 
 3062      thisQt = thisQt->getPointeeType();
 
 3072      const cling::Interpreter &interp,
 
 3073      std::set<const clang::CXXRecordDecl *> &visitedDecls)
 
 3075   std::list<std::string> headers;
 
 3078   cling::Interpreter::PushTransactionRAII RAII(&interp);
 
 3081   if (!visitedDecls.insert(rcd.getCanonicalDecl()).second)
 
 3085   if (
const clang::ClassTemplateSpecializationDecl *tsd = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd)) {
 
 3088      for (
auto & tArg : tsd->getTemplateArgs().asArray()) {
 
 3089         if (clang::TemplateArgument::ArgKind::Type != tArg.getKind()) 
continue;
 
 3091         if (tArgQualType.isNull()) 
continue;
 
 3092         if (
const clang::CXXRecordDecl *tArgCxxRcd = tArgQualType->getAsCXXRecordDecl()) {
 
 3093            headers.splice(headers.end(), 
RecordDecl2Headers(*tArgCxxRcd, interp, visitedDecls));
 
 3100         for (
auto baseIt = tsd->bases_begin(); baseIt != tsd->bases_end(); baseIt++) {
 
 3102            if (baseQualType.isNull()) 
continue;
 
 3103            if (
const clang::CXXRecordDecl *baseRcdPtr = baseQualType->getAsCXXRecordDecl()) {
 
 3104               headers.splice(headers.end(), 
RecordDecl2Headers(*baseRcdPtr, interp, visitedDecls));
 
 3109         for (
auto declIt = tsd->decls_begin(); declIt != tsd->decls_end(); ++declIt) {
 
 3110            if (
const clang::FieldDecl *fieldDecl = llvm::dyn_cast<clang::FieldDecl>(*declIt)) {
 
 3112               if (fieldQualType.isNull()) continue ;
 
 3113               if (
const clang::CXXRecordDecl *fieldCxxRcd = fieldQualType->getAsCXXRecordDecl()) {
 
 3114                  if (fieldCxxRcd->hasDefinition())
 
 3115                     headers.splice(headers.end(), 
RecordDecl2Headers(*fieldCxxRcd, interp, visitedDecls));
 
 3121         for (
auto methodIt = tsd->method_begin(); methodIt != tsd->method_end(); ++methodIt) {
 
 3123            for (
auto & fPar : methodIt->parameters()) {
 
 3125               if (fParQualType.isNull()) 
continue;
 
 3126               if (
const clang::CXXRecordDecl *fParCxxRcd = fParQualType->getAsCXXRecordDecl()) {
 
 3127                  if (fParCxxRcd->hasDefinition())
 
 3128                     headers.splice(headers.end(), 
RecordDecl2Headers(*fParCxxRcd, interp, visitedDecls));
 
 3133            if (retQualType.isNull()) 
continue;
 
 3134            if (
const clang::CXXRecordDecl *retCxxRcd = retQualType->getAsCXXRecordDecl()) {
 
 3135               if (retCxxRcd->hasDefinition())
 
 3144   headers.emplace_back(header);
 
 3157   if (
auto dclCtxt= rcd.getDeclContext()){
 
 3158      if (! dclCtxt->isStdNamespace()){
 
 3167   auto clAsTmplSpecDecl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&rcd);
 
 3168   if (!clAsTmplSpecDecl) 
return false;
 
 3173   auto& astCtxt = rcd.getASTContext();
 
 3174   auto& templInstArgs = clAsTmplSpecDecl->getTemplateInstantiationArgs();
 
 3175   for (
auto&& arg : templInstArgs.asArray()){
 
 3177      auto argKind = arg.getKind();
 
 3178      if (argKind != clang::TemplateArgument::Type){
 
 3179         if (argKind == clang::TemplateArgument::Integral) 
continue;
 
 3183      auto argQualType = arg.getAsType();
 
 3184      auto isPOD = argQualType.isPODType(astCtxt);
 
 3186      if (isPOD) 
continue;
 
 3188      auto argType = argQualType.getTypePtr();
 
 3189      if (
auto recType = llvm::dyn_cast<clang::RecordType>(argType)){
 
 3192         if (isArgGoodForAutoParseMap) 
continue;
 
 3211                            const cling::Interpreter &interp)
 
 3213   std::set<const clang::CXXRecordDecl *> visitedDecls;
 
 3214   std::unordered_set<std::string> buffer;
 
 3215   std::string autoParseKey;
 
 3218   for (
auto & annotatedRcd : annotatedRcds) {
 
 3219      if (
const clang::CXXRecordDecl *cxxRcd =
 
 3220               llvm::dyn_cast_or_null<clang::CXXRecordDecl>(annotatedRcd.GetRecordDecl())) {
 
 3222         visitedDecls.clear();
 
 3226         headers.remove_if([&buffer](
const std::string & s) {
 
 3227            return !buffer.insert(s).second;
 
 3230         if (autoParseKey.empty()) autoParseKey = annotatedRcd.GetNormalizedName();
 
 3232            headersDeclsMap[autoParseKey] = headers;
 
 3233            headersDeclsMap[annotatedRcd.GetRequestedName()] = headers;
 
 3235            ROOT::TMetaUtils::Info(
nullptr, 
"Class %s is not included in the set of autoparse keys.\n", autoParseKey.c_str());
 
 3240         if (!llvm::isa<clang::ClassTemplateSpecializationDecl>(cxxRcd)){
 
 3241            headersClassesMap[autoParseKey] = headersDeclsMap[autoParseKey];
 
 3242            headersClassesMap[annotatedRcd.GetRequestedName()] = headersDeclsMap[annotatedRcd.GetRequestedName()];
 
 3248   for (
auto & tDef : tDefDecls) {
 
 3249      if (clang::CXXRecordDecl *cxxRcd = tDef->getUnderlyingType()->getAsCXXRecordDecl()) {
 
 3251         visitedDecls.clear();
 
 3256         headers.remove_if([&buffer](
const std::string & s) {
 
 3257            return !buffer.insert(s).second;
 
 3260         if (autoParseKey.empty()) autoParseKey = tDef->getQualifiedNameAsString();
 
 3261         headersDeclsMap[autoParseKey] = headers;
 
 3266   for (
auto & func : funcDecls) {
 
 3272   for (
auto & var : varDecls) {
 
 3278   for (
auto & en : enumDecls) {
 
 3288                                         const cling::Interpreter &interp)
 
 3290   std::string newFwdDeclString;
 
 3294   std::string fwdDeclString;
 
 3296   std::unordered_set<std::string> fwdDecls;
 
 3317   std::vector<const clang::Decl *> selectedDecls(scan.
fSelectedClasses.size());
 
 3322                   selectedDecls.begin(),
 
 3326      selectedDecls.push_back(TD);
 
 3331   std::string fwdDeclLogs;
 
 3339      std::cout << 
"Logs from forward decl printer: \n" 
 3356   if (fwdDeclString.empty()) fwdDeclString = 
"";
 
 3357   return fwdDeclString;
 
 3364      const std::string &detectedUmbrella,
 
 3365      bool payLoadOnly = 
false)
 
 3367   std::string headerName;
 
 3370      std::cout << 
"Class-headers Mapping:\n";
 
 3371   std::string headersClassesMapString = 
"";
 
 3372   for (
auto const & classHeaders : headersClassesMap) {
 
 3374         std::cout << 
" o " << classHeaders.first << 
" --> ";
 
 3375      headersClassesMapString += 
"\"";
 
 3376      headersClassesMapString += classHeaders.first + 
"\"";
 
 3377      for (
auto const & header : classHeaders.second) {
 
 3378         headerName = (detectedUmbrella == header || payLoadOnly) ? 
"payloadCode" : 
"\"" + header + 
"\"";
 
 3379         headersClassesMapString += 
", " + headerName;
 
 3381            std::cout << 
", " << headerName;
 
 3386         std::cout << std::endl;
 
 3387      headersClassesMapString += 
", \"@\",\n";
 
 3389   headersClassesMapString += 
"nullptr";
 
 3390   return headersClassesMapString;
 
 3413   static const std::vector<std::string> namePrfxes {
 
 3416   auto pos = find_if(namePrfxes.begin(),
 
 3418                      [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
 
 3419   return namePrfxes.end() == pos;
 
 3426   static const std::vector<std::string> uclNamePrfxes {
 
 3430   static const std::set<std::string> unsupportedClassesNormNames{
 
 3433   if ( unsupportedClassesNormNames.count(
name) == 1) 
return false;
 
 3434   auto pos = find_if(uclNamePrfxes.begin(),
 
 3435                      uclNamePrfxes.end(),
 
 3436                      [&](
const std::string& str){return ROOT::TMetaUtils::BeginsWith(name,str);});
 
 3437   return uclNamePrfxes.end() == pos;
 
 3447   for (
auto&& aRcd : annotatedRcds){
 
 3448      auto clName = aRcd.GetNormalizedName();
 
 3450         std::cerr << 
"Error: Class " << clName << 
" has been selected but " 
 3451               << 
"currently the support for its I/O is not yet available. Note that " 
 3452               << clName << 
", even if not selected, will be available for " 
 3453               << 
"interpreted code.\n";
 
 3457         std::cerr << 
"Error: It is not necessary to explicitly select class " 
 3458                   << clName << 
". I/O is supported for it transparently.\n";
 
 3470    bool isLocked = 
false;
 
 3473      InterpreterCallbacks(interp),
 
 3474      fFilesIncludedByLinkdef(filesIncludedByLinkdef){};
 
 3479                                   llvm::StringRef FileName, 
bool IsAngled, clang::CharSourceRange ,
 
 3480                                   const clang::FileEntry * , llvm::StringRef ,
 
 3481                                   llvm::StringRef , 
const clang::Module * ,
 
 3482                                   clang::SrcMgr::CharacteristicKind )
 
 3484      if (isLocked) 
return;
 
 3485      if (IsAngled) 
return;
 
 3486      auto& PP = m_Interpreter->getCI()->getPreprocessor();
 
 3487      auto curLexer = PP.getCurrentFileLexer();
 
 3488      if (!curLexer) 
return;
 
 3489      auto fileEntry = curLexer->getFileEntry();
 
 3490      if (!fileEntry) 
return;
 
 3491      auto thisFileName = fileEntry->getName();
 
 3492      auto fileNameAsString = FileName.str();
 
 3494      if (isThisLinkdef) {
 
 3496         if (isTheIncludedLinkdef) {
 
 3497            fFilesIncludedByLinkdef.clear();
 
 3500            fFilesIncludedByLinkdef.emplace_back(fileNameAsString.c_str());
 
 3514                                 clang::SourceLocation ImportLoc,
 
 3517      using namespace clang;
 
 3518      if (llvm::StringRef(M->Name).endswith(
"ACLiC_dict")) {
 
 3519         Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
 
 3520         HeaderSearch& HS = PP.getHeaderSearchInfo();
 
 3522         Module* CoreModule = HS.lookupModule(
"Core", 
false);
 
 3523         assert(M && 
"Must have module Core");
 
 3524         PP.makeModuleVisible(CoreModule, ImportLoc);
 
 3529static llvm::cl::list<std::string>
 
 3532                     llvm::cl::desc(
"The list of the expected implicit modules build as part of building the current module."),
 
 3535static llvm::cl::opt<std::string>
 
 3537                      llvm::cl::desc(
"<output dictionary file>"),
 
 3557      : fChild(Child), fOwnsChild(OwnsChild), fMap(Map)
 
 3569      using namespace clang::diag;
 
 3575      std::string moduleName;
 
 3576      const clang::Module *module = 
nullptr;
 
 3579      const auto &ID = 
Info.getID();
 
 3580      if (ID == remark_module_build || ID == remark_module_build_done) {
 
 3581         moduleName = 
Info.getArgStdStr(0);
 
 3582         module = fMap.findModule(moduleName);
 
 3588                                      "Couldn't find module %s in the available modulemaps. This" 
 3589                                      "prevents us from correctly diagnosing wrongly built modules.\n",
 
 3590                                      moduleName.c_str());
 
 3603      bool isByproductModule
 
 3605      if (!isByproductModule)
 
 3606         fChild->HandleDiagnostic(DiagLevel, 
Info);
 
 3608      if (ID == remark_module_build && !isByproductModule) {
 
 3610                                 "Building module '%s' implicitly. If '%s' requires a \n" 
 3611                                 "dictionary please specify build dependency: '%s' depends on '%s'.\n" 
 3612                                 "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n",
 
 3614                                 moduleName.c_str(), moduleName.c_str());
 
 3622      DiagnosticConsumer::clear();
 
 3625   virtual void BeginSourceFile(
const clang::LangOptions &LangOpts, 
const clang::Preprocessor *PP)
 override 
 3627      fChild->BeginSourceFile(LangOpts, PP);
 
 3628      DiagnosticConsumer::BeginSourceFile(LangOpts, PP);
 
 3633      fChild->EndSourceFile();
 
 3634      DiagnosticConsumer::EndSourceFile();
 
 3640      DiagnosticConsumer::finish();
 
 3647#if defined(_WIN32) && defined(_MSC_VER) 
 3651   const char *EnablePopups = getenv(
"Cling_GuiOnAssert");
 
 3652   if (EnablePopups == 
nullptr || EnablePopups[0] == 
'0') {
 
 3653      ::_set_error_mode(_OUT_TO_STDERR);
 
 3654      _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
 
 3655      _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
 
 3656      _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
 
 3657      _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
 
 3658      _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
 
 3659      _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
 
 3664static llvm::cl::opt<bool> 
gOptForce(
"f", llvm::cl::desc(
"Overwrite <file>s."),
 
 3666static llvm::cl::opt<bool> 
gOptRootBuild(
"rootbuild", llvm::cl::desc(
"If we are building ROOT."),
 
 3677static llvm::cl::opt<VerboseLevel>
 
 3679                llvm::cl::values(clEnumVal(
v, 
"Show errors."),
 
 3680                                 clEnumVal(
v0, 
"Show only fatal errors."),
 
 3681                                 clEnumVal(
v1, 
"Show errors (the same as -v)."),
 
 3682                                 clEnumVal(
v2, 
"Show warnings (default)."),
 
 3683                                 clEnumVal(
v3, 
"Show notes."),
 
 3684                                 clEnumVal(
v4, 
"Show information.")),
 
 3688static llvm::cl::opt<bool>
 
 3689gOptCint(
"cint", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
 
 3692static llvm::cl::opt<bool>
 
 3693gOptReflex(
"reflex", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
 
 3696static llvm::cl::opt<bool>
 
 3697gOptGccXml(
"gccxml", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
 
 3700static llvm::cl::opt<std::string>
 
 3702                 llvm::cl::desc(
"An ACLiC feature which exports the list of dependent libraries."),
 
 3705static llvm::cl::opt<bool>
 
 3707               llvm::cl::desc(
"Generates a pch file from a predefined set of headers. See makepch.py."),
 
 3710static llvm::cl::opt<bool>
 
 3711gOptC(
"c", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
 
 3713static llvm::cl::opt<bool>
 
 3714gOptP(
"p", llvm::cl::desc(
"Deprecated, legacy flag which is ignored."),
 
 3716static llvm::cl::list<std::string>
 
 3718                   llvm::cl::desc(
"Generate rootmap file."),
 
 3720static llvm::cl::opt<std::string>
 
 3722                   llvm::cl::desc(
"Generate a rootmap file with the specified name."),
 
 3724static llvm::cl::opt<bool>
 
 3726             llvm::cl::desc(
"Generate a C++ module."),
 
 3728static llvm::cl::list<std::string>
 
 3730                   llvm::cl::desc(
"Specify a C++ modulemap file."),
 
 3733static llvm::cl::opt<bool>
 
 3735                  llvm::cl::desc(
"A single header including all headers instead of specifying them on the command line."),
 
 3737static llvm::cl::opt<bool>
 
 3739             llvm::cl::desc(
"If this library has multiple separate LinkDef files."),
 
 3741static llvm::cl::opt<bool>
 
 3743             llvm::cl::desc(
"Do not declare {using namespace std} in dictionary global scope."),
 
 3745static llvm::cl::opt<bool>
 
 3747                   llvm::cl::desc(
"Generate minimal dictionary for interactivity (without IO information)."),
 
 3749static llvm::cl::opt<bool>
 
 3751         llvm::cl::desc(
"Split the dictionary into two parts: one containing the IO (ClassDef)\ 
 3752information and another the interactivity support."),
 
 3754static llvm::cl::opt<bool>
 
 3757                   llvm::cl::desc(
"Do not run the selection rules. Useful when in -onepcm mode."),
 
 3759static llvm::cl::opt<std::string>
 
 3761                     llvm::cl::desc(
"The path to the library of the built dictionary."),
 
 3763static llvm::cl::list<std::string>
 
 3765                      llvm::cl::desc(
"The list of dependent modules of the dictionary."),
 
 3767static llvm::cl::list<std::string>
 
 3769                llvm::cl::desc(
"Do not store the <path> in the dictionary."),
 
 3773static llvm::cl::opt<bool>
 
 3775               llvm::cl::desc(
"Does not generate #include <header> but expands the header content."),
 
 3783static llvm::cl::opt<bool>
 
 3786                     llvm::cl::desc(
"Does not include the header files as it assumes they exist in the pch."),
 
 3788static llvm::cl::opt<bool>
 
 3790                        llvm::cl::desc(
"Check the selection syntax only."),
 
 3792static llvm::cl::opt<bool>
 
 3794                  llvm::cl::desc(
"Fail if there are warnings."),
 
 3796static llvm::cl::opt<bool>
 
 3798                  llvm::cl::desc(
"Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."),
 
 3800static llvm::cl::opt<std::string>
 
 3802            llvm::cl::desc(
"Specify an isysroot."),
 
 3804            llvm::cl::init(
"-"));
 
 3805static llvm::cl::list<std::string>
 
 3807                llvm::cl::desc(
"Specify an include path."),
 
 3809static llvm::cl::list<std::string>
 
 3811                    llvm::cl::desc(
"Specify a compiler default include path, to suppress unneeded `-isystem` arguments."),
 
 3813static llvm::cl::list<std::string>
 
 3815                    llvm::cl::desc(
"Specify a system include path."),
 
 3817static llvm::cl::list<std::string>
 
 3819             llvm::cl::desc(
"Specify defined macros."),
 
 3821static llvm::cl::list<std::string>
 
 3823             llvm::cl::desc(
"Specify undefined macros."),
 
 3825static llvm::cl::list<std::string>
 
 3827          llvm::cl::desc(
"Specify compiler diagnostics options."),
 
 3830static llvm::cl::list<std::string>
 
 3832                         llvm::cl::desc(
"<list of dictionary header files> <LinkDef file>"),
 
 3834static llvm::cl::list<std::string>
 
 3836         llvm::cl::desc(
"Consumes all unrecognized options."),
 
 3839static llvm::cl::SubCommand
 
 3842static llvm::cl::list<std::string>
 
 3844                  llvm::cl::desc(
"Consumes options and sends them to cling."),
 
 3854                                  std::vector<std::string> &missingHeaders)
 
 3857   std::vector<clang::Module::Header> moduleHeaders;
 
 3859      [&moduleHeaders](
const clang::Module::Header &
h) { moduleHeaders.push_back(
h); });
 
 3861   bool foundAllHeaders = 
true;
 
 3866   for (
const std::string &header : modGen.
GetHeaders()) {
 
 3867      bool headerFound = 
false;
 
 3868      for (
const clang::Module::Header &moduleHeader : moduleHeaders) {
 
 3869         if (header == moduleHeader.NameAsWritten) {
 
 3875         missingHeaders.push_back(header);
 
 3876         foundAllHeaders = 
false;
 
 3879   return foundAllHeaders;
 
 3885                             llvm::StringRef LinkdefPath, 
const std::string &moduleName)
 
 3887   clang::CompilerInstance *CI = interpreter.getCI();
 
 3888   clang::HeaderSearch &headerSearch = CI->getPreprocessor().getHeaderSearchInfo();
 
 3889   headerSearch.loadTopLevelSystemModules();
 
 3892   clang::Module *module = headerSearch.lookupModule(llvm::StringRef(moduleName));
 
 3897                              moduleName.c_str());
 
 3904   std::vector<std::string> missingHeaders;
 
 3907      std::stringstream msgStream;
 
 3908      msgStream << 
"warning: Couldn't find in " 
 3909                << module->PresumedModuleMapFile
 
 3910                << 
" the following specified headers in " 
 3911                << 
"the module " << module->Name << 
":\n";
 
 3912      for (
auto &
H : missingHeaders) {
 
 3913         msgStream << 
"  " << 
H << 
"\n";
 
 3915      std::string warningMessage = msgStream.str();
 
 3917      bool maybeUmbrella = modGen.
GetHeaders().size() == 1;
 
 3928         ROOT::TMetaUtils::Info(
"CheckModuleValid, %s. You can silence this message by adding %s to the invocation.",
 
 3929                                warningMessage.c_str(),
 
 3938                                 module->Name.c_str());
 
 3948   llvm::StringRef moduleName = llvm::sys::path::filename(rdictName);
 
 3949   moduleName.consume_front(
"lib");
 
 3950   moduleName.consume_back(
".pcm");
 
 3951   moduleName.consume_back(
"_rdict");
 
 3959              bool isGenreflex = 
false)
 
 3962   auto &opts = llvm::cl::getRegisteredOptions();
 
 3963   auto &optHelp = *opts[
"help"];
 
 3964   llvm::cl::alias optHelpAlias1(
"h",
 
 3965                      llvm::cl::desc(
"Alias for -help"),
 
 3966                      llvm::cl::aliasopt(optHelp));
 
 3967   llvm::cl::alias optHelpAlias2(
"?",
 
 3968                      llvm::cl::desc(
"Alias for -help"),
 
 3969                      llvm::cl::aliasopt(optHelp));
 
 3980   const char *executableFileName = argv[0];
 
 3982   llvm::sys::PrintStackTraceOnErrorSignal(executableFileName);
 
 3983   llvm::PrettyStackTraceProgram X(argc, argv);
 
 3986#if defined(R__WIN32) && !defined(R__WINGCC) 
 3991   for (
int iic = 1 ; iic < argc; ++iic) {
 
 3992      std::string iiarg(argv[iic]);
 
 3994         size_t len = iiarg.length();
 
 3996         char *argviic = 
new char[len + 1];
 
 3997         strlcpy(argviic, iiarg.c_str(), len + 1);
 
 3998         argv[iic] = argviic;
 
 4006   llvm::cl::ParseCommandLineOptions(argc, argv, 
"rootcling");
 
 4010      std::vector<const char *> clingArgsC;
 
 4011      clingArgsC.push_back(executableFileName);
 
 4013      clingArgsC.push_back(
"-I");
 
 4020         clingArgsC.push_back(Opt.c_str());
 
 4022      auto interp = llvm::make_unique<cling::Interpreter>(clingArgsC.size(),
 
 4024                                                          llvmResourceDir.c_str());
 
 4027      return interp->getDiagnostics().hasFatalErrorOccurred();
 
 4030   std::string dictname;
 
 4044      llvm::cl::PrintHelpMessage();
 
 4059      if ((fp = fopen(filein.c_str(), 
"r")) == 
nullptr) {
 
 4060         ROOT::TMetaUtils::Error(
nullptr, 
"%s: The input list file %s does not exist\n", executableFileName, filein.c_str());
 
 4087      ROOT::TMetaUtils::Error(
nullptr, 
"Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n");
 
 4088      llvm::cl::PrintHelpMessage();
 
 4092   std::vector<std::string> clingArgs;
 
 4093   clingArgs.push_back(executableFileName);
 
 4094   clingArgs.push_back(
"-iquote.");
 
 4100   std::list<std::string> diagnosticPragmas = {
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\""};
 
 4106      if (GetErrorIgnoreLevel() > 
kWarning)
 
 4108      GetWarningsAreErrors() = 
true;
 
 4122      ROOT::TMetaUtils::Error(
"", 
"Multidict requested but no target library. Please specify one with the -s argument.\n");
 
 4127      clingArgs.push_back(std::string(
"-D") + PPDefine);
 
 4130      clingArgs.push_back(std::string(
"-U") + PPUndefine);
 
 4133      clingArgs.push_back(std::string(
"-I") + llvm::sys::path::convert_to_slash(IncludePath));
 
 4140         clingArgs.push_back(
"-isystem");
 
 4141         clingArgs.push_back(llvm::sys::path::convert_to_slash(IncludePath));
 
 4145   for (
const std::string &WDiag : 
gOptWDiags) {
 
 4146      const std::string FullWDiag = std::string(
"-W") + WDiag;
 
 4150      clingArgs.push_back(FullWDiag);
 
 4154   clingArgs.push_back(std::string(
"-I") + includeDir);
 
 4156   std::vector<std::string> pcmArgs;
 
 4157   for (
size_t parg = 0, 
n = clingArgs.size(); parg < 
n; ++parg) {
 
 4158      auto thisArg = clingArgs[parg];
 
 4160      if (thisArg == 
"-c" ||
 
 4164         unsigned int offset = 2; 
 
 4165         char c = thisArg[offset];
 
 4166         while (
c == 
' ') 
c = thisArg[++offset];
 
 4170                                            [&](
const std::string& path){
 
 4171                                               return ROOT::TMetaUtils::BeginsWith(&thisArg[offset], path);});
 
 4172         if (excludePathsEnd != excludePathPos) 
continue;
 
 4174      pcmArgs.push_back(thisArg);
 
 4181      clingArgs.push_back(
"-D__ROOTCLING__");
 
 4184   clingArgs.push_back(
"-DSYSTEM_TYPE_macosx");
 
 4185#elif defined(R__WIN32) 
 4186   clingArgs.push_back(
"-DSYSTEM_TYPE_winnt");
 
 4189   clingArgs.push_back(
"-D_XKEYCHECK_H");
 
 4191   clingArgs.push_back(
"-DNOMINMAX");
 
 4193   clingArgs.push_back(
"-DSYSTEM_TYPE_unix");
 
 4196   clingArgs.push_back(
"-fsyntax-only");
 
 4198   clingArgs.push_back(
"-fPIC");
 
 4200   clingArgs.push_back(
"-Xclang");
 
 4201   clingArgs.push_back(
"-fmodules-embed-all-files");
 
 4202   clingArgs.push_back(
"-Xclang");
 
 4203   clingArgs.push_back(
"-main-file-name");
 
 4204   clingArgs.push_back(
"-Xclang");
 
 4205   clingArgs.push_back((dictname + 
".h").c_str());
 
 4213   std::string outputFile;
 
 4215   llvm::StringRef moduleName;
 
 4220   auto clingArgsInterpreter = clingArgs;
 
 4229      clingArgsInterpreter.push_back(
"-fmodules");
 
 4230      clingArgsInterpreter.push_back(
"-fno-implicit-module-maps");
 
 4233         clingArgsInterpreter.push_back(
"-fmodule-map-file=" + modulemap);
 
 4235      clingArgsInterpreter.push_back(
"-fmodule-map-file=" +
 
 4237                                     "/module.modulemap");
 
 4239      if (llvm::sys::fs::exists(ModuleMapCWD))
 
 4240         clingArgsInterpreter.push_back(
"-fmodule-map-file=" + ModuleMapCWD);
 
 4247      clingArgsInterpreter.push_back(
"-fmodule-name");
 
 4248      clingArgsInterpreter.push_back(moduleName.str());
 
 4258      if (moduleName == 
"Core") {
 
 4260         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"_Builtin_intrinsics.pcm").str().c_str());
 
 4261         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"_Builtin_stddef_max_align_t.pcm").str().c_str());
 
 4262         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"Cling_Runtime.pcm").str().c_str());
 
 4263         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"Cling_Runtime_Extra.pcm").str().c_str());
 
 4265         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"vcruntime.pcm").str().c_str());
 
 4266         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"services.pcm").str().c_str());
 
 4270         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"Darwin.pcm").str().c_str());
 
 4272         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"libc.pcm").str().c_str());
 
 4274         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"std.pcm").str().c_str());
 
 4275         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"boost.pcm").str().c_str());
 
 4276         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"tinyxml2.pcm").str().c_str());
 
 4277         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"ROOT_Config.pcm").str().c_str());
 
 4278         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"ROOT_Rtypes.pcm").str().c_str());
 
 4279         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"ROOT_Foundation_C.pcm").str().c_str());
 
 4280         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"ROOT_Foundation_Stage1_NoRTTI.pcm").str().c_str());
 
 4281      } 
else if (moduleName == 
"MathCore") {
 
 4282         remove((moduleCachePath + llvm::sys::path::get_separator() + 
"Vc.pcm").str().c_str());
 
 4287      clingArgsInterpreter.push_back(
"-fmodules-cache-path=" + moduleCachePath);
 
 4291      clingArgsInterpreter.push_back(
"-v");
 
 4294   std::vector<const char *> clingArgsC;
 
 4295   for (
auto const &clingArg : clingArgsInterpreter) {
 
 4297         std::cerr << 
"Argument \""<< clingArg << 
"\" is not a supported cling argument. " 
 4298                   << 
"This could be mistyped rootcling argument. Please check the commandline.\n";
 
 4301      clingArgsC.push_back(clingArg.c_str());
 
 4305   std::unique_ptr<cling::Interpreter> owningInterpPtr;
 
 4306   cling::Interpreter* interpPtr = 
nullptr;
 
 4308   std::list<std::string> filesIncludedByLinkdef;
 
 4312      clingArgsC.push_back(
"-ffast-math");
 
 4315      owningInterpPtr.reset(
new cling::Interpreter(clingArgsC.size(), &clingArgsC[0],
 
 4316                                                   llvmResourceDir.c_str()));
 
 4317      interpPtr = owningInterpPtr.get();
 
 4320      clingArgsC.push_back(
"-resource-dir");
 
 4321      clingArgsC.push_back(llvmResourceDir.c_str());
 
 4322      clingArgsC.push_back(
nullptr); 
 
 4324      extraArgs = &clingArgsC[1]; 
 
 4327         std::unique_ptr<TRootClingCallbacks> callBacks (
new TRootClingCallbacks(interpPtr, filesIncludedByLinkdef));
 
 4328         interpPtr->setCallbacks(std::move(callBacks));
 
 4331   cling::Interpreter &interp = *interpPtr;
 
 4332   clang::CompilerInstance *CI = interp.getCI();
 
 4334   CI->getFrontendOpts().ModulesEmbedAllFiles = 
true;
 
 4335   CI->getSourceManager().setAllFilesAreTransient(
true);
 
 4337   clang::Preprocessor &PP = CI->getPreprocessor();
 
 4338   clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
 
 4339   clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
 
 4340   auto &diags = interp.getDiagnostics();
 
 4347   diags.setSeverity(clang::diag::remark_module_build, clang::diag::Severity::Remark, clang::SourceLocation());
 
 4352   diags.setClient(recordingClient, 
true);
 
 4358      interp.DumpIncludePath();
 
 4363      interp.printIncludedFiles(llvm::outs());
 
 4364      llvm::outs() << 
"\n\n";
 
 4365      llvm::outs().flush();
 
 4368      const clang::LangOptions& LangOpts
 
 4369         = interp.getCI()->getASTContext().getLangOpts();
 
 4370#define LANGOPT(Name, Bits, Default, Description) \ 
 4371      ROOT::TMetaUtils::Info(0, "%s = %d // %s\n", #Name, (int)LangOpts.Name, Description);
 
 4372#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) 
 4373#include "clang/Basic/LangOptions.def" 
 4377   interp.getOptions().ErrorOut = 
true;
 
 4378   interp.enableRawInput(
true);
 
 4382         if (DepMod.endswith(
"_rdict.pcm")) {
 
 4389         cling::Interpreter::PushTransactionRAII RAII(&interp);
 
 4390         if (!interp.loadModule(DepMod, 
false)) {
 
 4399      if (interp.declare(
"#include <assert.h>\n" 
 4400                         "#include \"Rtypes.h\"\n" 
 4401                         "#include \"TObject.h\"") != cling::Interpreter::kSuccess
 
 4409   if (interp.declare(
"#include <string>\n"  
 4410                      "#include <RtypesCore.h>\n"  
 4411                      "namespace std {} using namespace std;") != cling::Interpreter::kSuccess) {
 
 4422   clingArgs.push_back(
"-D__CINT__");
 
 4423   clingArgs.push_back(
"-D__MAKECINT__");
 
 4429   std::string interpPragmaSource;
 
 4430   std::string includeForSource;
 
 4431   std::string interpreterDeclarations;
 
 4432   std::string linkdef;
 
 4438      if (isSelectionFile) {
 
 4440            linkdef = optHeaderFileName;
 
 4443                                    executableFileName, optHeaderFileName.c_str());
 
 4449      std::string fullheader(optHeaderFileName);
 
 4452      if (fullheader[fullheader.length() - 1] == 
'+') {
 
 4453         fullheader.erase(fullheader.length() - 1);
 
 4458      interpPragmaSource += std::string(
"#include \"") + header + 
"\"\n";
 
 4459      if (!isSelectionFile) {
 
 4467         includeForSource += std::string(
"#include \"") + fullheader + 
"\"\n";
 
 4468         pcmArgs.push_back(header);
 
 4470         interpreterDeclarations += std::string(
"#include \"") + header + 
"\"\n";
 
 4475      bool hasSelectionFile = !linkdef.empty();
 
 4476      unsigned expectedHeaderFilesSize = 1 + hasSelectionFile;
 
 4487      if (!newName.empty())
 
 4500      string incCurDir = 
"-I";
 
 4501      incCurDir += currentDirectory;
 
 4502      pcmArgs.push_back(incCurDir);
 
 4507      std::stringstream res;
 
 4508      const char* delim=
"\n";
 
 4509      std::copy(diagnosticPragmas.begin(),
 
 4510                diagnosticPragmas.end(),
 
 4511                std::ostream_iterator<std::string>(res, delim));
 
 4512      if (interp.declare(res.str()) != cling::Interpreter::kSuccess) {
 
 4518   class IgnoringPragmaHandler: 
public clang::PragmaNamespace {
 
 4520      IgnoringPragmaHandler(
const char* pragma):
 
 4521         clang::PragmaNamespace(pragma) {}
 
 4522      void HandlePragma(clang::Preprocessor &PP,
 
 4523                        clang::PragmaIntroducer Introducer,
 
 4524                        clang::Token &tok) {
 
 4525         PP.DiscardUntilEndOfDirective();
 
 4531   PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"link"));
 
 4532   PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"extra_include"));
 
 4533   PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"read"));
 
 4534   PP.AddPragmaHandler(
new IgnoringPragmaHandler(
"create"));
 
 4536   if (!interpreterDeclarations.empty() &&
 
 4537       interp.declare(interpreterDeclarations) != cling::Interpreter::kSuccess) {
 
 4549      pcmArgs.push_back(linkdef);
 
 4557         interp.AddIncludePath(inclPath);
 
 4559      std::stringstream definesUndefinesStr;
 
 4562      if (!definesUndefinesStr.str().empty()) {
 
 4563         if (interp.declare(definesUndefinesStr.str()) != cling::Interpreter::kSuccess) {
 
 4564            ROOT::TMetaUtils::Error(
nullptr, 
"Failed to parse -D, -U flags as preprocessor directives:\n%s", definesUndefinesStr.str().c_str());
 
 4575   if (linkdef.empty()) {
 
 4581   std::ofstream fileout;
 
 4583   std::ostream *splitDictStream = 
nullptr;
 
 4584   std::unique_ptr<std::ostream> splitDeleter(
nullptr);
 
 4606         splitDeleter.reset(splitDictStream);
 
 4608         splitDictStream = &dictStream;
 
 4611      size_t dh = main_dictname.rfind(
'.');
 
 4612      if (dh != std::string::npos) {
 
 4613         main_dictname.erase(dh);
 
 4616      std::string main_dictname_copy(main_dictname);
 
 4638   string linkdefFilename;
 
 4639   if (linkdef.empty()) {
 
 4640      linkdefFilename = 
"in memory";
 
 4642      bool found = 
Which(interp, linkdef.c_str(), linkdefFilename);
 
 4650   std::vector<std::pair<std::string, std::string>> namesForExclusion;
 
 4656   SelectionRules selectionRules(interp, normCtxt, namesForExclusion);
 
 4658   std::string extraIncludes;
 
 4663   const unsigned int selRulesInitialSize = selectionRules.
Size();
 
 4667   bool dictSelRulesPresent = selectionRules.
Size() > selRulesInitialSize;
 
 4671   int rootclingRetCode(0);
 
 4673   if (linkdef.empty()) {
 
 4678      clingArgs.push_back(
"-Ietc/cling/cint"); 
 
 4680      if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
 
 4681                       llvmResourceDir.c_str())) {
 
 4683         rootclingRetCode += 1;
 
 4693   } 
else if (isSelXML) {
 
 4697      std::ifstream 
file(linkdefFilename.c_str());
 
 4698      if (
file.is_open()) {
 
 4702         if (!xmlr.
Parse(linkdefFilename.c_str(), selectionRules)) {
 
 4715      std::ifstream 
file(linkdefFilename.c_str());
 
 4716      if (
file.is_open()) {
 
 4726      clingArgs.push_back(
"-Ietc/cling/cint"); 
 
 4728      if (!ldefr.
Parse(selectionRules, interpPragmaSource, clingArgs,
 
 4729                       llvmResourceDir.c_str())) {
 
 4731         rootclingRetCode += 1;
 
 4766      dictStream << 
"#include \"TBuffer.h\"\n" 
 4767                 << 
"#include \"TVirtualObject.h\"\n" 
 4768                 << 
"#include <vector>\n" 
 4769                 << 
"#include \"TSchemaHelper.h\"\n\n";
 
 4771      std::list<std::string> includes;
 
 4773      for (
auto & incFile : includes) {
 
 4774         dictStream << 
"#include <" << incFile << 
">" << std::endl;
 
 4776      dictStream << std::endl;
 
 4781   int scannerVerbLevel = 0;
 
 4784      scannerVerbLevel = GetErrorIgnoreLevel() == 
kInfo; 
 
 4786         scannerVerbLevel = GetErrorIgnoreLevel() < 
kWarning;
 
 4809   scan.
Scan(CI->getASTContext());
 
 4811   bool has_input_error = 
false;
 
 4818         !dictSelRulesPresent &&
 
 4825      if (rootclingRetCode) 
return rootclingRetCode;
 
 4832         if (annRcd.RequestNoInputOperator()) {
 
 4844   if (has_input_error) {
 
 4854      for (
auto &&includedFromLinkdef : filesIncludedByLinkdef) {
 
 4855         includeForSource += 
"#include \"" + includedFromLinkdef + 
"\"\n";
 
 4883         constructorTypes.emplace_back(
"TRootIOCtor", interp);
 
 4884         constructorTypes.emplace_back(
"__void__", interp); 
 
 4885         constructorTypes.emplace_back(
"", interp);
 
 4915   if (rootclingRetCode != 0) {
 
 4916      return rootclingRetCode;
 
 4935      std::string detectedUmbrella;
 
 4936      for (
auto & arg : pcmArgs) {
 
 4938            detectedUmbrella = arg;
 
 4944         headersDeclsMap.clear();
 
 4948      std::string headersClassesMapString = 
"\"\"";
 
 4949      std::string fwdDeclsString = 
"\"\"";
 
 4965         if (modGen.
IsPCH()) {
 
 4968            if (!
CheckModuleValid(modGen, llvmResourceDir, interp, linkdefFilename, moduleName.str()))
 
 4978      ofstream outputfile(liblist_filename.c_str(), ios::out);
 
 4981                                 executableFileName, liblist_filename.c_str());
 
 4983         const size_t endStr = 
gLibsNeeded.find_last_not_of(
" \t");
 
 4984         outputfile << 
gLibsNeeded.substr(0, endStr + 1) << endl;
 
 4986         outputfile << 
"# Now the list of classes\n";
 
 4991            outputfile << annRcd.GetNormalizedName() << endl;
 
 4998   if (0 != rootclingRetCode) 
return rootclingRetCode;
 
 5004   [](
const std::string & 
a, 
const std::string & 
b) -> std::string {
 
 5005      if (a.empty()) return b;
 
 5006      else return a + 
" " + b;
 
 5011   std::list<std::string> classesNames;
 
 5012   std::list<std::string> classesNamesForRootmap;
 
 5013   std::list<std::string> classesDefsList;
 
 5017                                                     classesNamesForRootmap,
 
 5021   std::list<std::string> enumNames;
 
 5026   std::list<std::string> varNames;
 
 5031   if (0 != rootclingRetCode) 
return rootclingRetCode;
 
 5034   if (rootMapNeeded) {
 
 5036      std::list<std::string> nsNames;
 
 5045                             rootmapLibName.c_str());
 
 5048      std::unordered_set<std::string> headersToIgnore;
 
 5051            headersToIgnore.insert(optHeaderFileName.c_str());
 
 5053      std::list<std::string> typedefsRootmapLines;
 
 5061                                          classesNamesForRootmap,
 
 5063                                          typedefsRootmapLines,
 
 5069      if (0 != rootclingRetCode) 
return 1;
 
 5079      cling::Interpreter::PushTransactionRAII RAII(&interp);
 
 5080      CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
 
 5091   if(rootclingRetCode == 0) {
 
 5092      rootclingRetCode += tmpCatalog.
commit();
 
 5097   return rootclingRetCode;
 
 5108      unsigned int numberOfHeaders = 0;
 
 5109      for (std::vector<std::string>::iterator it = headersNames.begin();
 
 5110            it != headersNames.end(); ++it) {
 
 5111         const std::string headername(*it);
 
 5116                                      "*** genreflex: %s is not a valid header name (.h and .hpp extensions expected)!\n",
 
 5117                                      headername.c_str());
 
 5120      return numberOfHeaders;
 
 5126   unsigned int extractArgs(
int argc, 
char **argv, std::vector<std::string> &args)
 
 5129      unsigned int argvCounter = 0;
 
 5130      for (
int i = 1; i < argc; ++i) {
 
 5133            args.push_back(argv[i]);
 
 5135         } 
else  if (argvCounter) {
 
 5136            argv[i - argvCounter] = argv[i];
 
 5143         std::cout << 
"Args: \n";
 
 5144         for (std::vector<std::string>::iterator it = args.begin();
 
 5145               it < args.end(); ++it) {
 
 5146            std::cout << i << 
") " << *it << std::endl;
 
 5159      size_t result = filename.find_last_of(
'.');
 
 5160      if (std::string::npos != result) {
 
 5161         filename.erase(result);
 
 5162         filename.append(newExtension);
 
 5172      const unsigned int size(str.size());
 
 5173      char *
a = 
new char[
size + 1];
 
 5175      memcpy(
a, str.c_str(), 
size);
 
 5191                             std::vector<std::string> &ofilesnames)
 
 5193      ofilesnames.reserve(headersNames.size());
 
 5195      for (std::vector<std::string>::const_iterator it = headersNames.begin();
 
 5196            it != headersNames.end(); ++it) {
 
 5197         std::string ofilename(*it);
 
 5199         ofilesnames.push_back(ofilename);
 
 5206                       const std::vector<std::string> &argsToBeAdded,
 
 5207                       const std::string &optName = 
"")
 
 5209      for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
 
 5210            it != argsToBeAdded.end(); ++it) {
 
 5218                            const std::vector<std::string> &argsToBeAdded,
 
 5219                            const std::string &optName = 
"")
 
 5221      for (std::vector<std::string>::const_iterator it = argsToBeAdded.begin();
 
 5222            it != argsToBeAdded.end(); ++it) {
 
 5223         if (optName.length()) {
 
 5233                       const std::string &selectionFileName,
 
 5234                       const std::string &targetLibName,
 
 5236                       const std::vector<std::string> &pcmsNames,
 
 5237                       const std::vector<std::string> &includes,
 
 5238                       const std::vector<std::string> &preprocDefines,
 
 5239                       const std::vector<std::string> &preprocUndefines,
 
 5240                       const std::vector<std::string> &warnings,
 
 5241                       const std::string &rootmapFileName,
 
 5242                       const std::string &rootmapLibName,
 
 5243                       bool interpreteronly,
 
 5246                       bool writeEmptyRootPCM,
 
 5248                       bool noIncludePaths,
 
 5249                       bool noGlobalUsingStd,
 
 5250                       const std::vector<std::string> &headersNames,
 
 5251                       bool failOnWarnings,
 
 5252                       const std::string &ofilename)
 
 5256      std::vector<char *> argvVector;
 
 5267      std::string dictLocation;
 
 5273      std::string newRootmapLibName(rootmapLibName);
 
 5274      if (!rootmapFileName.empty() && newRootmapLibName.empty()) {
 
 5275         if (headersNames.size() != 1) {
 
 5277                                      "*** genreflex: No rootmap lib and several header specified!\n");
 
 5280         newRootmapLibName = 
"lib";
 
 5281         newRootmapLibName += cleanHeaderName;
 
 5287      std::string newRootmapFileName(rootmapFileName);
 
 5288      if (!newRootmapFileName.empty() && !
HasPath(newRootmapFileName)) {
 
 5289         newRootmapFileName = dictLocation + newRootmapFileName;
 
 5294      if (!newRootmapFileName.empty()) {
 
 5300      if (!newRootmapLibName.empty()) {
 
 5306      if (interpreteronly)
 
 5314      if (!targetLibName.empty()) {
 
 5324      if (noGlobalUsingStd)
 
 5334      if (writeEmptyRootPCM)
 
 5357      if (!selectionFileName.empty()) {
 
 5361      const int argc = argvVector.size();
 
 5365         std::cout << 
"Rootcling commandline:\n";
 
 5366         for (
int i = 0; i < argc; i++)
 
 5367            std::cout << i << 
") " << argvVector[i] << std::endl;
 
 5370      char **argv =  & (argvVector[0]);
 
 5375      for (
int i = 0; i < argc; i++)
 
 5376         delete [] argvVector[i];
 
 5378      return rootclingReturnCode;
 
 5387                           const std::string &selectionFileName,
 
 5388                           const std::string &targetLibName,
 
 5390                           const std::vector<std::string> &pcmsNames,
 
 5391                           const std::vector<std::string> &includes,
 
 5392                           const std::vector<std::string> &preprocDefines,
 
 5393                           const std::vector<std::string> &preprocUndefines,
 
 5394                           const std::vector<std::string> &warnings,
 
 5395                           const std::string &rootmapFileName,
 
 5396                           const std::string &rootmapLibName,
 
 5397                           bool interpreteronly,
 
 5400                           bool writeEmptyRootPCM,
 
 5402                           bool noIncludePaths,
 
 5403                           bool noGlobalUsingStd,
 
 5404                           const std::vector<std::string> &headersNames,
 
 5405                           bool failOnWarnings,
 
 5406                           const std::string &outputDirName_const = 
"")
 
 5408      std::string outputDirName(outputDirName_const);
 
 5410      std::vector<std::string> ofilesNames;
 
 5417      std::vector<std::string> namesSingleton(1);
 
 5418      for (
unsigned int i = 0; i < headersNames.size(); ++i) {
 
 5419         namesSingleton[0] = headersNames[i];
 
 5420         std::string ofilenameFullPath(ofilesNames[i]);
 
 5421         if (llvm::sys::path::parent_path(ofilenameFullPath) == 
"")
 
 5422            ofilenameFullPath = outputDirName + ofilenameFullPath;
 
 5444         if (returnCode != 0)
 
 5459                           std::vector<std::string> &values)
 
 5462   if (options[oIndex]) {
 
 5463      const int nVals = options[oIndex].count();
 
 5464      values.reserve(nVals);
 
 5465      int optionIndex = 0;
 
 5468                                              << optionIndex << 
"/" << nVals << 
" " 
 5469                                              << opt->arg << std::endl;
 
 5471         values.push_back(opt->arg);
 
 5482                          const char *descriptor)
 
 5484   if (options[optionIndex]) {
 
 5486                                "*** genereflex: %s is not supported anymore.\n",
 
 5543   enum  optionIndex { UNKNOWN,
 
 5574   enum  optionTypes { NOTYPE, STRING } ;
 
 5577   const char *genreflexUsage =
 
 5578      "Generates dictionary sources and related ROOT pcm starting from an header.\n" 
 5579      "Usage: genreflex headerfile.h [opts] [preproc. opts]\n\n" 
 5582   const char *selectionFilenameUsage =
 
 5583      "-s, --selection_file\tSelection filename\n" 
 5584      "      Class selection file to specify for which classes the dictionary\n" 
 5585      "      will be generated. The final set can be crafted with exclusion and\n" 
 5586      "      exclusion rules.\n" 
 5587      "      Properties can be specified. Some have special meaning:\n" 
 5588      "      - name [string] name of the entity to select with an exact matching\n" 
 5589      "      - pattern [string] name with wildcards (*) to select entities\n" 
 5590      "      - file_name/file_pattern [string]: as name/pattern but referring to\n" 
 5591      "        file where the C++ entities reside and not to C++ entities themselves.\n" 
 5592      "      - transient/persistent [string: true/false] The fields to which they are\n" 
 5593      "        applied will not be persistified if requested.\n" 
 5594      "      - comment [string]: what you could write in code after an inline comment\n" 
 5595      "        without \"//\". For example comment=\"!\" or \"||\".\n" 
 5596      "      - noStreamer [true/false]: turns off streamer generation if set to 'true.'\n" 
 5597      "        Default value is 'false'\n" 
 5598      "      - noInputOperator [true/false]: turns off input operator generation if set\n" 
 5599      "        to 'true'. Default value is 'false'\n" 
 5603      "          <class [name=\"classname\"] [pattern=\"wildname\"]\n" 
 5604      "                 [file_name=\"filename\"] [file_pattern=\"wildname\"]\n" 
 5605      "                 [id=\"xxxx\"] [noStreamer=\"true/false\"]\n" 
 5606      "                 [noInputOperator=\"true/false\"] />\n" 
 5607      "          <class name=\"classname\" >\n" 
 5608      "            <field name=\"m_transient\" transient=\"true\"/>\n" 
 5609      "            <field name=\"m_anothertransient\" persistent=\"false\"/>\n" 
 5610      "            <field name=\"m_anothertransient\" comment=\"||\"/>\n" 
 5611      "            <properties prop1=\"value1\" [prop2=\"value2\"]/>\n" 
 5613      "          <function [name=\"funcname\"] [pattern=\"wildname\"] />\n" 
 5614      "          <enum [name=\"enumname\"] [pattern=\"wildname\"] />\n" 
 5615      "          <variable [name=\"varname\"] [pattern=\"wildname\"] />\n" 
 5618      "          <class [name=\"classname\"] [pattern=\"wildname\"] />\n" 
 5619      "            <method name=\"unwanted\" />\n" 
 5624      "      If no selection file is specified, the class with the filename without\n" 
 5625      "      extension will be selected, i.e. myClass.h as argument without any\n" 
 5626      "      selection xml comes with an implicit selection rule for class \"myClass\".\n";
 
 5628   const char *outputFilenameUsage =
 
 5629      "-o, --output\tOutput filename\n" 
 5630      "      Output file name. If an existing directory is specified instead of a file,\n" 
 5631      "      then a filename will be built using the name of the input file and will\n" 
 5632      "      be placed in the given directory. <headerfile>_rflx.cpp.\n" 
 5633      "      NOTA BENE: the dictionaries that will be used within the same project must\n" 
 5634      "      have unique names.\n";
 
 5637   const char *targetLib =
 
 5638      "-l, --library\tTarget library\n" 
 5639      "      The flag -l must be followed by the name of the library that will\n" 
 5640      "      contain the object file corresponding to the dictionary produced by\n" 
 5641      "      this invocation of genreflex.\n" 
 5642      "      The name takes priority over the one specified for the rootmapfile.\n" 
 5643      "      The name influences the name of the created pcm:\n" 
 5644      "       1) If it is not specified, the pcm is called libINPUTHEADER_rdict.pcm\n" 
 5645      "       2) If it is specified, the pcm is called libTARGETLIBRARY_rdict.pcm\n" 
 5646      "          Any \"liblib\" occurence is transformed in the expected \"lib\".\n" 
 5647      "       3) If this is specified in conjunction with --multiDict, the output is\n" 
 5648      "          libTARGETLIBRARY_DICTIONARY_rdict.pcm\n";
 
 5650   const char *rootmapUsage =
 
 5651      "--rootmap\tGenerate the rootmap file to be used by ROOT.\n" 
 5652      "      This file lists the autoload keys. For example classes for which the\n" 
 5653      "      reflection information is provided.\n" 
 5654      "      The format of the rootmap is the following:\n" 
 5655      "        - Forward declarations section\n" 
 5656      "        - Libraries sections\n" 
 5657      "      Rootmaps can be concatenated together, for example with the cat util.\n" 
 5658      "      In order for ROOT to pick up the information in the rootmaps, they\n" 
 5659      "      have to be located in the library path and have the .rootmap extension.\n" 
 5660      "      An example rootmap file could be:\n" 
 5662      "      template <class T> class A;\n" 
 5663      "      [ libMyLib.so ]\n" 
 5664      "      class A<double>\n" 
 5669   const char *rootmapLibUsage =
 
 5670      "--rootmap-lib\tLibrary name for the rootmap file.\n";
 
 5703         "--multiDict\tSupport for many dictionaries in one library\n" 
 5704         "      Form correct pcm names if multiple dictionaries will be in the same\n" 
 5705         "      library (needs target library switch. See its documentation).\n" 
 5712         "" , 
"noGlobalUsingStd" ,
 
 5714         "--noGlobalUsingStd\tDo not declare {using namespace std} in the dictionary global scope\n" 
 5715         "      All header files must have sumbols from std:: namespace fully qualified\n" 
 5721         "s" , 
"selection_file" ,
 
 5723         selectionFilenameUsage
 
 5737         "" , 
"rootmap-lib" ,
 
 5745         "" , 
"interpreteronly",
 
 5747         "--interpreteronly\tDo not generate I/O related information.\n" 
 5748         "      Generate minimal dictionary required for interactivity.\n" 
 5756         "--split\tSplit the dictionary\n" 
 5757         "      Split in two the dictionary, isolating the part with\n" 
 5758         "      ClassDef related functions in a separate file.\n" 
 5766         "-m \tPcm file loaded before any header (option can be repeated).\n" 
 5774         "-v, --verbose\tPrint some debug information.\n" 
 5782         "--debug\tPrint all debug information.\n" 
 5790         "--quiet\tPrint only warnings and errors (default).\n" 
 5798         "--silent\tPrint no information at all.\n" 
 5804         "" , 
"writeEmptyPCM",
 
 5806         "--writeEmptyPCM\tWrite an empty ROOT pcm.\n" 
 5814         "--cxxmodule\tGenerates a PCM for C++ Modules.\n" 
 5823         "--help\tPrint usage and exit.\n" 
 5829         "", 
"fail_on_warnings",
 
 5831         "--fail_on_warnings\tFail on warnings and errors.\n" 
 5837         "", 
"selSyntaxOnly",
 
 5839         "--selSyntaxOnly\tValidate selection file w/o generating the dictionary.\n" 
 5845         "" , 
"noIncludePaths",
 
 5847         "--noIncludePaths\tDo not store the headers' directories in the dictionary. Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.\n" 
 5886         "" , 
"no_membertypedefs" ,
 
 5894         "" , 
"no_templatetypedefs" ,
 
 5899      {0, 0, 
nullptr, 
nullptr, 
nullptr, 
nullptr}
 
 5902   std::vector<std::string> headersNames;
 
 5903   const int originalArgc = argc;
 
 5905   const int extractedArgs = extractArgs(argc, argv, headersNames);
 
 5907   const int offset = 1; 
 
 5908   argc -= offset + extractedArgs;
 
 5913   std::vector<ROOT::option::Option> options(stats.
options_max);
 
 5914   std::vector<ROOT::option::Option> buffer(stats.
buffer_max);
 
 5920   if (parse.
error()) {
 
 5926   if (options[HELP] || originalArgc == 1) {
 
 5931   int numberOfHeaders = checkHeadersNames(headersNames);
 
 5932   if (0 == numberOfHeaders) {
 
 5943   std::string verbosityOption(
"-v2");
 
 5944   if (options[SILENT]) verbosityOption = 
"-v0";
 
 5945   if (options[
VERBOSE] || getenv (
"VERBOSE")) verbosityOption = 
"-v3";
 
 5946   if (options[
DEBUG]) verbosityOption = 
"-v4";
 
 5951   std::string selectionFileName;
 
 5952   if (options[SELECTIONFILENAME]) {
 
 5953      selectionFileName = options[SELECTIONFILENAME].arg;
 
 5956                                 "Invalid selection file extension: filename is %s and extension .xml is expected!\n",
 
 5957                                 selectionFileName.c_str());
 
 5972   std::string rootmapFileName(options[ROOTMAP].arg ? options[ROOTMAP].arg : 
"");
 
 5973   std::string rootmapLibName(options[ROOTMAPLIB].arg ? options[ROOTMAPLIB].arg : 
"");
 
 5976   std::string targetLibName;
 
 5977   if (options[TARGETLIB]) {
 
 5978      targetLibName = options[TARGETLIB].arg;
 
 5981                                 "Invalid target library extension: filename is %s and extension %s is expected!\n",
 
 5982                                 targetLibName.c_str(),
 
 5986      if (options[ROOTMAP]) {
 
 5991   bool isCxxmodule = options[CXXMODULE];
 
 5993   bool multidict = 
false;
 
 5994   if (options[MULTIDICT]) multidict = 
true;
 
 5996   bool noGlobalUsingStd = 
false;
 
 5997   if (options[NOGLOBALUSINGSTD]) noGlobalUsingStd = 
true;
 
 5999   if (multidict && targetLibName.empty()) {
 
 6001                              "Multilib support is requested but no target lib is specified. A sane pcm name cannot be formed.\n");
 
 6005   bool interpreteronly = 
false;
 
 6006   if (options[INTERPRETERONLY])
 
 6007      interpreteronly = 
true;
 
 6009   bool doSplit = 
false;
 
 6013   bool writeEmptyRootPCM = 
false;
 
 6014   if (options[WRITEEMPTYROOTPCM])
 
 6015      writeEmptyRootPCM = 
true;
 
 6017   bool selSyntaxOnly = 
false;
 
 6018   if (options[SELSYNTAXONLY]) {
 
 6019      selSyntaxOnly = 
true;
 
 6022   bool noIncludePaths = 
false;
 
 6023   if (options[NOINCLUDEPATHS]) {
 
 6024      noIncludePaths = 
true;
 
 6027   bool failOnWarnings = 
false;
 
 6028   if (options[FAILONWARNINGS]) {
 
 6029      failOnWarnings = 
true;
 
 6038   std::vector<std::string> pcmsNames;
 
 6042   std::vector<std::string> preprocDefines;
 
 6046   std::vector<std::string> preprocUndefines;
 
 6050   std::vector<std::string> includes;
 
 6054   std::vector<std::string> warnings;
 
 6065   int returnValue = 0;
 
 6066   std::string ofileName(options[OFILENAME] ? options[OFILENAME].arg : 
"");
 
 6070   if (!ofileName.empty() && !llvm::sys::fs::is_directory(ofileName)) {
 
 6071      returnValue = invokeRootCling(verbosityOption,
 
 6094      returnValue = invokeManyRootCling(verbosityOption,
 
 6127   assert(!
gDriverConfig && 
"Driver configuration already set!");
 
 6147   if (std::string::npos != exeName.find(
"genreflex"))
 
 6155      ROOT::TMetaUtils::Info(
nullptr,
"Problems have been detected during the generation of the dictionary.\n");
 
Select classes and assign properties using C++ syntax.
 
The file contains utilities which are foundational and could be used across the core component of ROO...
 
This is the only file required to use The Lean Mean C++ Option Parser.
 
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
 
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
 
const AttributesMap_t & GetAttributes() const
 
std::unordered_map< std::string, std::string > AttributesMap_t
 
Custom diag client for clang that verifies that each implicitly build module is a system module.
 
CheckModuleBuildClient(clang::DiagnosticConsumer *Child, bool OwnsChild, clang::ModuleMap &Map)
 
clang::DiagnosticConsumer * fChild
 
~CheckModuleBuildClient()
 
virtual void BeginSourceFile(const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) override
 
virtual void finish() override
 
virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override
 
virtual void clear() override
 
virtual bool IncludeInDiagnosticCounts() const override
 
virtual void EndSourceFile() override
 
const std::list< VariableSelectionRule > & GetFieldSelectionRules() const
 
bool LoadIncludes(std::string &extraInclude)
 
bool Parse(SelectionRules &sr, llvm::StringRef code, const std::vector< std::string > &parserArgs, const char *llvmdir)
 
void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
 
void WriteClassInit(std::ostream &strm, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const ROOT::TMetaUtils::RConstructorTypes &, bool &needCollectionProxy, void(*emitStreamerInfo)(const char *))
 
void WriteUmbrellaHeader(std::ostream &out) const
Write a header file pulling in the content of this module through a series of #defined,...
 
const std::string & GetUmbrellaName() const
 
const std::vector< std::string > & GetIncludePaths() const
 
void WriteRegistrationSource(std::ostream &out, const std::string &fwdDeclnArgsToKeepString, const std::string &headersClassesMapString, const std::string &fwdDeclsString, const std::string &extraIncludes, bool hasCxxModule) const
 
const std::vector< std::string > & GetHeaders() const
 
void WriteContentHeader(std::ostream &out) const
Write a header file describing the content of this module through a series of variables inside the na...
 
int GetErrorCount() const
 
const std::string & GetModuleFileName() const
 
std::ostream & WritePPUndefines(std::ostream &out) const
Write #ifdef FOO.
 
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)
 
virtual void EnteredSubmodule(clang::Module *M, clang::SourceLocation ImportLoc, bool ForPragma)
 
virtual void InclusionDirective(clang::SourceLocation, const clang::Token &, llvm::StringRef FileName, bool IsAngled, clang::CharSourceRange, const clang::FileEntry *, llvm::StringRef, llvm::StringRef, const clang::Module *, clang::SrcMgr::CharacteristicKind)
 
std::list< std::string > & fFilesIncludedByLinkdef
 
TRootClingCallbacks(cling::Interpreter *interp, std::list< std::string > &filesIncludedByLinkdef)
 
bool Parse(const std::string &fileName, SelectionRules &out)
 
Little helper class to bookkeep the files names which we want to make temporary.
 
void addFileName(std::string &nameStr)
Adds the name and the associated temp name to the catalog.
 
const std::string & getFileName(const std::string &tmpFileName)
 
std::vector< std::string > m_names
 
std::vector< std::string > m_tempNames
 
const std::string m_emptyString
 
std::string getTmpFileName(const std::string &filename)
 
static bool FromCygToNativePath(std::string &path)
 
std::string GetCurrentDir()
 
std::string MakePathRelative(const std::string &path, const std::string &base, bool isBuildingROOT=false)
 
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.
 
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
 
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
 
void Init(TClassEdit::TInterpreterLookupHelper *helper)
 
void header2outputName(std::string &fileName)
Replace the extension with "_rflx.cpp".
 
void AddToArgVectorSplit(std::vector< char * > &argvVector, const std::vector< std::string > &argsToBeAdded, const std::string &optName="")
 
void changeExtension(std::string &filename, const std::string &newExtension)
 
int invokeRootCling(const std::string &verbosity, const std::string &selectionFileName, const std::string &targetLibName, bool multiDict, const std::vector< std::string > &pcmsNames, const std::vector< std::string > &includes, const std::vector< std::string > &preprocDefines, const std::vector< std::string > &preprocUndefines, const std::vector< std::string > &warnings, const std::string &rootmapFileName, const std::string &rootmapLibName, bool interpreteronly, bool doSplit, bool isCxxmodule, bool writeEmptyRootPCM, bool selSyntaxOnly, bool noIncludePaths, bool noGlobalUsingStd, const std::vector< std::string > &headersNames, bool failOnWarnings, const std::string &ofilename)
 
int invokeManyRootCling(const std::string &verbosity, const std::string &selectionFileName, const std::string &targetLibName, bool multiDict, const std::vector< std::string > &pcmsNames, const std::vector< std::string > &includes, const std::vector< std::string > &preprocDefines, const std::vector< std::string > &preprocUndefines, const std::vector< std::string > &warnings, const std::string &rootmapFileName, const std::string &rootmapLibName, bool interpreteronly, bool doSplit, bool isCxxmodule, bool writeEmptyRootPCM, bool selSyntaxOnly, bool noIncludePaths, bool noGlobalUsingStd, const std::vector< std::string > &headersNames, bool failOnWarnings, const std::string &outputDirName_const="")
Get the right ofilenames and invoke several times rootcling One invokation per header.
 
unsigned int checkHeadersNames(std::vector< std::string > &headersNames)
Loop on arguments: stop at the first which starts with -.
 
void headers2outputsNames(const std::vector< std::string > &headersNames, std::vector< std::string > &ofilesnames)
Get a proper name for the output file.
 
char * string2charptr(const std::string &str)
The caller is responsible for deleting the string!
 
unsigned int extractArgs(int argc, char **argv, std::vector< std::string > &args)
Extract the arguments from the command line.
 
void AddToArgVector(std::vector< char * > &argvVector, const std::vector< std::string > &argsToBeAdded, const std::string &optName="")
 
int FinalizeStreamerInfoWriting(cling::Interpreter &interp, bool writeEmptyRootPCM=false)
Make up for skipping RegisterModule, now that dictionary parsing is done and these headers cannot be ...
 
std::list< std::string > CollapseIdenticalNamespaces(const std::list< std::string > &fwdDeclarationsList)
If two identical namespaces are there, just declare one only Example: namespace A { namespace B { fwd...
 
static llvm::cl::opt< bool > gOptC("c", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::cat(gRootclingOptions))
 
void RiseWarningIfPresent(std::vector< ROOT::option::Option > &options, int optionIndex, const char *descriptor)
 
int RootClingMain(int argc, char **argv, bool isGenreflex=false)
 
static llvm::StringRef GetModuleNameFromRdictName(llvm::StringRef rdictName)
 
static llvm::cl::opt< bool > gOptGccXml("gccxml", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::opt< std::string > gOptISysRoot("isysroot", llvm::cl::Prefix, llvm::cl::Hidden, llvm::cl::desc("Specify an isysroot."), llvm::cl::cat(gRootclingOptions), llvm::cl::init("-"))
 
int STLContainerStreamer(const clang::FieldDecl &m, int rwmode, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
Create Streamer code for an STL container.
 
std::string ExtractFileName(const std::string &path)
Extract the filename from a fullpath.
 
static llvm::cl::opt< bool > gOptRootBuild("rootbuild", llvm::cl::desc("If we are building ROOT."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
 
bool IsImplementationName(const std::string &filename)
 
const std::string gLibraryExtension(".so")
 
static llvm::cl::list< std::string > gOptSink(llvm::cl::ZeroOrMore, llvm::cl::Sink, llvm::cl::desc("Consumes all unrecognized options."), llvm::cl::cat(gRootclingOptions))
 
int GenReflexMain(int argc, char **argv)
Translate the arguments of genreflex into rootcling ones and forward them to the RootCling function.
 
static void MaybeSuppressWin32CrashDialogs()
 
void RecordDeclCallback(const clang::RecordDecl *recordDecl)
 
void CheckClassNameForRootMap(const std::string &classname, map< string, string > &autoloads)
 
bool Which(cling::Interpreter &interp, const char *fname, string &pname)
Find file name in path specified via -I statements to Cling.
 
void AdjustRootMapNames(std::string &rootmapFileName, std::string &rootmapLibName)
 
void AddNamespaceSTDdeclaration(std::ostream &dictStream)
 
static llvm::cl::list< std::string > gOptWDiags("W", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify compiler diagnostics options."), llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::opt< bool > gOptCint("cint", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::list< std::string > gOptModuleByproducts("mByproduct", llvm::cl::ZeroOrMore, llvm::cl::Hidden, llvm::cl::desc("The list of the expected implicit modules build as part of building the current module."), llvm::cl::cat(gRootclingOptions))
 
map< string, string > gAutoloads
 
static llvm::cl::opt< bool > gOptCheckSelectionSyntax("selSyntaxOnly", llvm::cl::desc("Check the selection syntax only."), llvm::cl::cat(gRootclingOptions))
 
static bool CheckModuleValid(TModuleGenerator &modGen, const std::string &resourceDir, cling::Interpreter &interpreter, llvm::StringRef LinkdefPath, const std::string &moduleName)
Check moduleName validity from modulemap. Check if this module is defined or not.
 
static void CheckForMinusW(std::string arg, std::list< std::string > &diagnosticPragmas)
Transform -W statements in diagnostic pragmas for cling reacting on "-Wno-" For example -Wno-deprecat...
 
static bool WriteAST(llvm::StringRef fileName, clang::CompilerInstance *compilerInstance, llvm::StringRef iSysRoot, clang::Module *module=nullptr)
Write the AST of the given CompilerInstance to the given File while respecting the given isysroot.
 
static llvm::cl::opt< bool > gOptUmbrellaInput("umbrellaHeader", llvm::cl::desc("A single header including all headers instead of specifying them on the command line."), llvm::cl::cat(gRootclingOptions))
 
void ExtractFilePath(const std::string &path, std::string &dirname)
Extract the path from a fullpath finding the last \ or / according to the content in gPathSeparator.
 
int STLStringStreamer(const clang::FieldDecl &m, int rwmode, std::ostream &dictStream)
Create Streamer code for a standard string object.
 
void CreateDictHeader(std::ostream &dictStream, const std::string &main_dictname)
 
const char * GetExePath()
Returns the executable path name, used e.g. by SetRootSys().
 
const std::string gPathSeparator(ROOT::TMetaUtils::GetPathSeparator())
 
static llvm::cl::list< std::string > gOptBareClingSink(llvm::cl::OneOrMore, llvm::cl::Sink, llvm::cl::desc("Consumes options and sends them to cling."), llvm::cl::cat(gRootclingOptions), llvm::cl::sub(gBareClingSubcommand))
 
bool InheritsFromTObject(const clang::RecordDecl *cl, const cling::Interpreter &interp)
 
static bool InjectModuleUtilHeader(const char *argv0, TModuleGenerator &modGen, cling::Interpreter &interp, bool umbrella)
Write the extra header injected into the module: umbrella header if (umbrella) else content header.
 
static llvm::cl::list< std::string > gOptModuleMapFiles("moduleMapFile", llvm::cl::desc("Specify a C++ modulemap file."), llvm::cl::cat(gRootclingOptions))
 
int ExtractClassesListAndDeclLines(RScanner &scan, std::list< std::string > &classesList, std::list< std::string > &classesListForRootmap, std::list< std::string > &fwdDeclarationsList, const cling::Interpreter &interpreter)
 
void ParseRootMapFileNewFormat(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map, using the new format.
 
static llvm::cl::OptionCategory gRootclingOptions("rootcling common options")
 
static llvm::cl::list< std::string > gOptSysIncludePaths("isystem", llvm::cl::ZeroOrMore, llvm::cl::desc("Specify a system include path."), llvm::cl::cat(gRootclingOptions))
 
void ExtractHeadersForDecls(const RScanner::ClassColl_t &annotatedRcds, const RScanner::TypedefColl_t tDefDecls, const RScanner::FunctionColl_t funcDecls, const RScanner::VariableColl_t varDecls, const RScanner::EnumColl_t enumDecls, HeadersDeclsMap_t &headersClassesMap, HeadersDeclsMap_t &headersDeclsMap, const cling::Interpreter &interp)
 
bool ParsePragmaLine(const std::string &line, const char *expectedTokens[], size_t *end=nullptr)
Check whether the #pragma line contains expectedTokens (0-terminated array).
 
static llvm::cl::opt< bool > gOptWriteEmptyRootPCM("writeEmptyRootPCM", llvm::cl::Hidden, llvm::cl::desc("Does not include the header files as it assumes they exist in the pch."), llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::opt< bool > gOptGeneratePCH("generate-pch", llvm::cl::desc("Generates a pch file from a predefined set of headers. See makepch.py."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
 
static bool GenerateAllDict(TModuleGenerator &modGen, clang::CompilerInstance *compilerInstance, const std::string ¤tDirectory)
Generates a PCH from the given ModuleGenerator and CompilerInstance.
 
void LoadLibraryMap(const std::string &fileListName, map< string, string > &autoloads)
Fill the map of libraries to be loaded in presence of a class Transparently support the old and new r...
 
std::ostream * CreateStreamPtrForSplitDict(const std::string &dictpathname, tempFileNamesCatalog &tmpCatalog)
Transform name of dictionary.
 
void WriteNamespaceInit(const clang::NamespaceDecl *cl, cling::Interpreter &interp, std::ostream &dictStream)
Write the code to initialize the namespace name and the initialization object.
 
static llvm::cl::list< std::string > gOptCompDefaultIncludePaths("compilerI", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify a compiler default include path, to suppress unneeded `-isystem` arguments."), llvm::cl::cat(gRootclingOptions))
 
void AnnotateAllDeclsForPCH(cling::Interpreter &interp, RScanner &scan)
We need annotations even in the PCH: // !, // || etc.
 
size_t GetFullArrayLength(const clang::ConstantArrayType *arrayType)
 
static llvm::cl::opt< bool > gOptSplit("split", llvm::cl::desc("Split the dictionary into two parts: one containing the IO (ClassDef)\
information and another the interactivity support."), llvm::cl::cat(gRootclingOptions))
 
bool ProcessAndAppendIfNotThere(const std::string &el, std::list< std::string > &el_list, std::unordered_set< std::string > &el_set)
Separate multiline strings.
 
static llvm::cl::opt< bool > gOptNoGlobalUsingStd("noGlobalUsingStd", llvm::cl::desc("Do not declare {using namespace std} in dictionary global scope."), llvm::cl::cat(gRootclingOptions))
 
const ROOT::Internal::RootCling::DriverConfig * gDriverConfig
 
static llvm::cl::list< std::string > gOptModuleDependencies("m", llvm::cl::desc("The list of dependent modules of the dictionary."), llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::SubCommand gBareClingSubcommand("bare-cling", "Call directly cling and exit.")
 
static llvm::cl::opt< bool > gOptInterpreterOnly("interpreteronly", llvm::cl::desc("Generate minimal dictionary for interactivity (without IO information)."), llvm::cl::cat(gRootclingOptions))
 
void WriteArrayDimensions(const clang::QualType &type, std::ostream &dictStream)
Write "[0]" for all but the 1st dimension.
 
void GetMostExternalEnclosingClassName(const clang::DeclContext &theContext, std::string &ctxtName, const cling::Interpreter &interpreter, bool treatParent=true)
Extract the proper autoload key for nested classes The routine does not erase the name,...
 
std::string GetFwdDeclnArgsToKeepString(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, cling::Interpreter &interp)
 
int ExtractAutoloadKeys(std::list< std::string > &names, const COLL &decls, const cling::Interpreter &interp)
 
static llvm::cl::opt< std::string > gOptSharedLibFileName("s", llvm::cl::desc("The path to the library of the built dictionary."), llvm::cl::cat(gRootclingOptions))
 
int GenerateFullDict(std::ostream &dictStream, cling::Interpreter &interp, RScanner &scan, const ROOT::TMetaUtils::RConstructorTypes &ctorTypes, bool isSplit, bool isGenreflex, bool writeEmptyRootPCM)
 
void WriteStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
 
bool IsGoodForAutoParseMap(const clang::RecordDecl &rcd)
Check if the class good for being an autoparse key.
 
void GetMostExternalEnclosingClassNameFromDecl(const clang::Decl &theDecl, std::string &ctxtName, const cling::Interpreter &interpreter)
 
static llvm::cl::opt< bool > gOptP("p", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::list< std::string > gOptDictionaryHeaderFiles(llvm::cl::Positional, llvm::cl::ZeroOrMore, llvm::cl::desc("<list of dictionary header files> <LinkDef file>"), llvm::cl::cat(gRootclingOptions))
 
void SetRootSys()
Set the ROOTSYS env var based on the executable location.
 
bool CheckInputOperator(const char *what, const char *proto, const string &fullname, const clang::RecordDecl *cl, cling::Interpreter &interp)
Check if the specified operator (what) has been properly declared if the user has requested a custom ...
 
void GenerateNecessaryIncludes(std::ostream &dictStream, const std::string &includeForSource, const std::string &extraIncludes)
 
void StrcpyArg(string &dest, const char *original)
Copy the command line argument, stripping MODULE/inc if necessary.
 
static llvm::cl::list< std::string > gOptRootmapLibNames("rml", llvm::cl::ZeroOrMore, llvm::cl::desc("Generate rootmap file."), llvm::cl::cat(gRootclingOptions))
 
void ParseRootMapFile(ifstream &file, map< string, string > &autoloads)
Parse the rootmap and add entries to the autoload map.
 
static llvm::cl::opt< bool > gOptCxxModule("cxxmodule", llvm::cl::desc("Generate a C++ module."), llvm::cl::cat(gRootclingOptions))
 
std::pair< std::string, std::string > GetExternalNamespaceAndContainedEntities(const std::string line)
Performance is not critical here.
 
void AddPlatformDefines(std::vector< std::string > &clingArgs)
 
static std::string GenerateFwdDeclString(const RScanner &scan, const cling::Interpreter &interp)
Generate the fwd declarations of the selected entities.
 
static llvm::cl::opt< bool > gOptFailOnWarnings("failOnWarnings", llvm::cl::desc("Fail if there are warnings."), llvm::cl::cat(gRootclingOptions))
 
const char * CopyArg(const char *original)
If the argument starts with MODULE/inc, strip it to make it the name we can use in #includes.
 
string GetNonConstMemberName(const clang::FieldDecl &m, const string &prefix="")
Return the name of the data member so that it can be used by non-const operation (so it includes a co...
 
static llvm::cl::list< std::string > gOptIncludePaths("I", llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::desc("Specify an include path."), llvm::cl::cat(gRootclingOptions))
 
void WriteAutoStreamer(const ROOT::TMetaUtils::AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, std::ostream &dictStream)
 
void ExtractSelectedNamespaces(RScanner &scan, std::list< std::string > &nsList)
Loop on selected classes and put them in a list.
 
static bool IncludeHeaders(const std::vector< std::string > &headers, cling::Interpreter &interpreter)
Includes all given headers in the interpreter.
 
clang::QualType GetPointeeTypeIfPossible(const clang::QualType &qt)
Get the pointee type if possible.
 
void AnnotateDecl(clang::CXXRecordDecl &CXXRD, const RScanner::DeclsSelRulesMap_t &declSelRulesMap, cling::Interpreter &interpreter, bool isGenreflex)
 
static llvm::cl::opt< VerboseLevel > gOptVerboseLevel(llvm::cl::desc("Choose verbosity level:"), llvm::cl::values(clEnumVal(v, "Show errors."), clEnumVal(v0, "Show only fatal errors."), clEnumVal(v1, "Show errors (the same as -v)."), clEnumVal(v2, "Show warnings (default)."), clEnumVal(v3, "Show notes."), clEnumVal(v4, "Show information.")), llvm::cl::init(v2), llvm::cl::cat(gRootclingOptions))
 
void GenerateLinkdef(llvm::cl::list< std::string > &InputFiles, std::string &code_for_parser)
 
static llvm::cl::opt< std::string > gOptRootMapFileName("rmf", llvm::cl::desc("Generate a rootmap file with the specified name."), llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::opt< bool > gOptInlineInput("inlineInputHeader", llvm::cl::desc("Does not generate #include <header> but expands the header content."), llvm::cl::cat(gRootclingOptions))
 
bool isPointerToPointer(const clang::FieldDecl &m)
 
int CreateNewRootMapFile(const std::string &rootmapFileName, const std::string &rootmapLibName, const std::list< std::string > &classesDefsList, const std::list< std::string > &classesNames, const std::list< std::string > &nsNames, const std::list< std::string > &tdNames, const std::list< std::string > &enNames, const std::list< std::string > &varNames, const HeadersDeclsMap_t &headersClassesMap, const std::unordered_set< std::string > headersToIgnore)
Generate a rootmap file in the new format, like { decls } namespace A { namespace B { template <typen...
 
static llvm::cl::opt< std::string > gOptDictionaryFileName(llvm::cl::Positional, llvm::cl::desc("<output dictionary file>"), llvm::cl::cat(gRootclingOptions))
 
bool IsSelectionXml(const char *filename)
 
bool IsGoodLibraryName(const std::string &name)
 
static llvm::cl::opt< bool > gOptReflex("reflex", llvm::cl::desc("Deprecated, legacy flag which is ignored."), llvm::cl::Hidden, llvm::cl::cat(gRootclingOptions))
 
static llvm::cl::opt< bool > gOptMultiDict("multiDict", llvm::cl::desc("If this library has multiple separate LinkDef files."), llvm::cl::cat(gRootclingOptions))
 
bool IsSelectionFile(const char *filename)
 
const std::string GenerateStringFromHeadersForClasses(const HeadersDeclsMap_t &headersClassesMap, const std::string &detectedUmbrella, bool payLoadOnly=false)
Generate a string for the dictionary from the headers-classes map.
 
bool IsSupportedClassName(const char *name)
 
static 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)
 
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.
 
R__DLLEXPORT int ROOT_rootcling_Driver(int argc, char **argv, const ROOT::Internal::RootCling::DriverConfig &config)
 
cling::Interpreter *(* fTCling__GetInterpreter)()
 
bool(* fCloseStreamerInfoROOTFile)(bool writeEmptyRootPCM)
 
void(* fAddEnumToROOTFile)(const char *tdname)
 
void(* fInitializeStreamerInfoROOTFile)(const char *filename)
 
const char *(* fTROOT__GetIncludeDir)()
 
void(* fAddTypedefToROOTFile)(const char *tdname)
 
const char *(* fTROOT__GetEtcDir)()
 
void(* fAddStreamerInfoToROOTFile)(const char *normName)
 
const char ***(* fTROOT__GetExtraInterpreterArgs)()
 
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
 
Describes an option, its help text (usage) and how it should be parsed.
 
static option::ArgStatus Required(const option::Option &option, bool msg)
 
Determines the minimum lengths of the buffer and options arrays used for Parser.
 
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
 
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
 
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
 
#define dest(otri, vertexptr)