diff --git a/core/metautils/inc/TMetaUtils.h b/core/metautils/inc/TMetaUtils.h index 165f5cb1eee9004435f7736f7314b4afdc0ab4b0..a9689ba6a1a67c3b69e15da87ffceb3499e13b32 100644 --- a/core/metautils/inc/TMetaUtils.h +++ b/core/metautils/inc/TMetaUtils.h @@ -193,15 +193,16 @@ public: //______________________________________________________________________________ class RConstructorType { private: - std::string fArgTypeName; + const std::string fArgTypeName; const clang::CXXRecordDecl *fArgType; public: RConstructorType(const char *type_of_arg, const cling::Interpreter&); - const char *GetName(); - const clang::CXXRecordDecl *GetType(); + const char *GetName() const ; + const clang::CXXRecordDecl *GetType() const; }; +typedef std::list<RConstructorType> RConstructorTypes; // Functions ------------------------------------------------------------------- @@ -228,7 +229,7 @@ const char* DataMemberInfo__ValidArrayIndex(const clang::FieldDecl &m, int *errn std::string GetROOTIncludeDir(bool rootbuild); //______________________________________________________________________________ -bool CheckConstructor(const clang::CXXRecordDecl*, RConstructorType&); +bool CheckConstructor(const clang::CXXRecordDecl*, const RConstructorType&); //______________________________________________________________________________ bool ClassInfo__HasMethod(const clang::RecordDecl *cl, char const*); @@ -264,7 +265,7 @@ bool HasCustomOperatorNewPlacement(clang::RecordDecl const&, const cling::Interp bool HasDirectoryAutoAdd(clang::CXXRecordDecl const*, const cling::Interpreter&); //______________________________________________________________________________ -bool HasIOConstructor(clang::CXXRecordDecl const*, std::string*, const cling::Interpreter&); +bool HasIOConstructor(clang::CXXRecordDecl const*, std::string&, const RConstructorTypes&, const cling::Interpreter&); //______________________________________________________________________________ bool HasNewMerge(clang::CXXRecordDecl const*, const cling::Interpreter&); @@ -362,14 +363,12 @@ std::string TrueName(const clang::FieldDecl &m); //______________________________________________________________________________ const clang::CXXRecordDecl *ScopeSearch(const char *name, const cling::Interpreter &gInterp, const clang::Type** resultType = 0); -//______________________________________________________________________________ -void AddConstructorType(const char *arg, const cling::Interpreter &interp); - //______________________________________________________________________________ void WriteAuxFunctions(std::ostream& finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, + const RConstructorTypes& ctorTypes, const TNormalizedCtxt &normCtxt); @@ -398,6 +397,7 @@ void WriteClassCode(CallWriteStreamer_t WriteStreamerFunc, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, std::ostream& finalString, + const RConstructorTypes& ctorTypes, bool isGenreflex); //______________________________________________________________________________ @@ -406,6 +406,7 @@ void WriteClassInit(std::ostream& finalString, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, + const RConstructorTypes& ctorTypes, bool& needCollectionProxy); //______________________________________________________________________________ diff --git a/core/metautils/src/RStl.cxx b/core/metautils/src/RStl.cxx index 809d3726517c52b79eb203bc54a30cf36c8a5a1b..d549a0b57c11f965e7940d361353221079f66f02 100644 --- a/core/metautils/src/RStl.cxx +++ b/core/metautils/src/RStl.cxx @@ -180,8 +180,11 @@ void ROOT::RStl::Print() } } -void ROOT::RStl::WriteClassInit(std::ostream &ostr, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, - bool &needCollectionProxy) +void ROOT::RStl::WriteClassInit(std::ostream &ostr, + const cling::Interpreter &interp, + const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, + const ROOT::TMetaUtils::RConstructorTypes& ctorTypes, + bool &needCollectionProxy) { // This function writes the TGeneraticClassInfo initialiser // and the auxiliary functions (new and delete wrappers) for @@ -210,9 +213,9 @@ void ROOT::RStl::WriteClassInit(std::ostream &ostr, const cling::Interpreter &in // std::string fullname = R__GetQualifiedName(*iter->GetRecordDecl()); // fprintf(stderr,"RStl is generating TClass for %ld %s %s %s\n",iter->GetRuleIndex(),iter->GetRequestedName(),iter->GetNormalizedName(),fullname.c_str()); - - ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, needCollectionProxy); - ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, normCtxt); + + ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy); + ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt); } } diff --git a/core/metautils/src/RStl.h b/core/metautils/src/RStl.h index 9738c933e93af3da935d0d80897231a384c40a54..9d0b2cfebbd99d9e6d4a2ec0d2ed592ed93ce13b 100644 --- a/core/metautils/src/RStl.h +++ b/core/metautils/src/RStl.h @@ -56,7 +56,11 @@ namespace ROOT { void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt); void GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt); void Print(); - void WriteClassInit(std::ostream &strm, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, bool &needCollectionProxy); + void WriteClassInit(std::ostream &strm, + const cling::Interpreter &interp, + const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, + const ROOT::TMetaUtils::RConstructorTypes&, + bool &needCollectionProxy); // void WriteStreamer(FILE *file,const clang::CXXRecordDecl *stlcl); // void WriteStreamer(FILE *file); diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx index 609defa987562e08b6afa716b3a583b8d86515ef..f5d623a1c3a6eb1137729fe293d1ac5f17377cd8 100644 --- a/core/metautils/src/TMetaUtils.cxx +++ b/core/metautils/src/TMetaUtils.cxx @@ -56,7 +56,7 @@ #include "TMetaUtils.h" int ROOT::TMetaUtils::gErrorIgnoreLevel = ROOT::TMetaUtils::kError; -std::vector<ROOT::TMetaUtils::RConstructorType> gIoConstructorTypes; +// std::vector<ROOT::TMetaUtils::RConstructorType> gIoConstructorTypes; namespace { @@ -1029,7 +1029,8 @@ int ROOT::TMetaUtils::ElementStreamer(std::ostream& finalString, } //______________________________________________________________________________ -bool ROOT::TMetaUtils::CheckConstructor(const clang::CXXRecordDecl *cl, RConstructorType &ioctortype) +bool ROOT::TMetaUtils::CheckConstructor(const clang::CXXRecordDecl *cl, + const RConstructorType &ioctortype) { const char *arg = ioctortype.GetName(); if ( (arg == 0 || arg[0] == '\0') && !cl->hasUserDeclaredConstructor() ) { @@ -1119,14 +1120,16 @@ namespace ROOT { if (!instanceType.isNull()) fArgType = instanceType->getAsCXXRecordDecl(); } - const char *RConstructorType::GetName() { return fArgTypeName.c_str(); } - const clang::CXXRecordDecl *RConstructorType::GetType() { return fArgType; } + const char *RConstructorType::GetName() const { return fArgTypeName.c_str(); } + const clang::CXXRecordDecl *RConstructorType::GetType() const { return fArgType; } } } - //______________________________________________________________________________ -bool ROOT::TMetaUtils::HasIOConstructor(const clang::CXXRecordDecl *cl, std::string *arg, const cling::Interpreter &interp) +bool ROOT::TMetaUtils::HasIOConstructor(const clang::CXXRecordDecl *cl, + std::string& arg, + const RConstructorTypes& ctorTypes, + const cling::Interpreter &interp) { // return true if we can find an constructor calleable without any arguments // or with one the IOCtor special types. @@ -1135,8 +1138,9 @@ bool ROOT::TMetaUtils::HasIOConstructor(const clang::CXXRecordDecl *cl, std::str if (cl->isAbstract()) return false; - for(unsigned int i = 0; i < gIoConstructorTypes.size(); ++i) { - std::string proto( gIoConstructorTypes[i].GetName() ); + for(RConstructorTypes::const_iterator ctorTypeIt=ctorTypes.begin(); + ctorTypeIt!=ctorTypes.end();++ctorTypeIt){ + std::string proto( ctorTypeIt->GetName() ); int extra = (proto.size()==0) ? 0 : 1; if (extra==0) { // Looking for default constructor @@ -1145,11 +1149,11 @@ bool ROOT::TMetaUtils::HasIOConstructor(const clang::CXXRecordDecl *cl, std::str proto += " *"; } - result = ROOT::TMetaUtils::CheckConstructor(cl, gIoConstructorTypes[i]); - if (result && extra && arg) { - *arg = "( ("; - *arg += proto; - *arg += ")0 )"; + result = ROOT::TMetaUtils::CheckConstructor(cl,*ctorTypeIt); + if (result && extra) { + arg = "( ("; + arg += proto; + arg += ")0 )"; } // Check for private operator new @@ -1620,6 +1624,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, + const RConstructorTypes& ctorTypes, bool& needCollectionProxy) { // FIXME: a function of ~300 lines! @@ -1657,7 +1662,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString, } - if (HasIOConstructor(decl,&args, interp)) { + if (HasIOConstructor(decl, args, ctorTypes, interp)) { finalString << " static void *new_" << mappedname.c_str() << "(void *p = 0);" << "\n"; if (args.size()==0 && NeedDestructor(decl)) @@ -1835,7 +1840,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString, rootflag = rootflag | TClassTable__kHasCustomStreamerMember; } finalString << "isa_proxy, " << rootflag << "," << "\n" << " sizeof(" << csymbol.c_str() << ") );" << "\n"; - if (HasIOConstructor(decl,&args, interp)) { + if (HasIOConstructor(decl, args, ctorTypes, interp)) { finalString << " instance.SetNew(&new_" << mappedname.c_str() << ");" << "\n"; if (args.size()==0 && NeedDestructor(decl)) finalString << " instance.SetNewArray(&newArray_" << mappedname.c_str() << ");" << "\n"; @@ -2264,6 +2269,7 @@ void ROOT::TMetaUtils::WriteAuxFunctions(std::ostream& finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, + const RConstructorTypes& ctorTypes, const TNormalizedCtxt &normCtxt) { // std::string NormalizedName; @@ -2295,7 +2301,7 @@ void ROOT::TMetaUtils::WriteAuxFunctions(std::ostream& finalString, finalString << "namespace ROOT {" << "\n"; std::string args; - if (HasIOConstructor(decl, &args, interp)) { + if (HasIOConstructor(decl, args, ctorTypes, interp)) { // write the constructor wrapper only for concrete classes finalString << " // Wrappers around operator new" << "\n"; finalString << " static void *new_" << mappedname.c_str() << "(void *p) {" << "\n" << " return p ? "; @@ -2655,6 +2661,7 @@ void ROOT::TMetaUtils::WriteClassCode(CallWriteStreamer_t WriteStreamerFunc, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, std::ostream& dictStream, + const RConstructorTypes& ctorTypes, bool isGenreflex=false) { // Generate the code of the class @@ -2691,13 +2698,7 @@ void ROOT::TMetaUtils::WriteClassCode(CallWriteStreamer_t WriteStreamerFunc, ROOT::TMetaUtils::WriteShowMembers(dictStream, cl, decl, interp, normCtxt, true); } } - ROOT::TMetaUtils::WriteAuxFunctions(dictStream, cl, decl, interp, normCtxt); -} - -//______________________________________________________________________________ -void ROOT::TMetaUtils::AddConstructorType(const char *arg, const cling::Interpreter &interp) -{ - if (arg) gIoConstructorTypes.push_back(ROOT::TMetaUtils::RConstructorType(arg, interp)); + ROOT::TMetaUtils::WriteAuxFunctions(dictStream, cl, decl, interp, ctorTypes, normCtxt); } //______________________________________________________________________________ diff --git a/core/utils/src/LinkdefReader.cxx b/core/utils/src/LinkdefReader.cxx index 4d47041f1bee9375bdc2d4093fb7791a9d0dbd69..7f4c1ad43fe78b591c61b9459b855923227911a3 100644 --- a/core/utils/src/LinkdefReader.cxx +++ b/core/utils/src/LinkdefReader.cxx @@ -100,7 +100,9 @@ void LinkdefReader::PopulateCppMap(){ LinkdefReader::fgMapCppNames["#else"] = kElse; } -LinkdefReader::LinkdefReader(cling::Interpreter &interp) : fLine(1), fCount(0), fIOCtorTypeCallback(0), fInterp(interp) +LinkdefReader::LinkdefReader(cling::Interpreter &interp, + ROOT::TMetaUtils::RConstructorTypes& IOConstructorTypes): + fLine(1), fCount(0), fIOConstructorTypesPtr(&IOConstructorTypes), fInterp(interp) { PopulatePragmaMap(); PopulateCppMap(); @@ -469,8 +471,7 @@ bool LinkdefReader::AddRule(std::string ruletype, std::string identifier, bool l break; case kIOCtorType: // #pragma link C++ IOCtorType typename; - if (fIOCtorTypeCallback) - fIOCtorTypeCallback(identifier.c_str(), fInterp); + fIOConstructorTypesPtr->push_back(ROOT::TMetaUtils::RConstructorType(identifier.c_str(), fInterp)); break; case kIgnore: // All the pragma that were supported in CINT but are currently not relevant for CLING @@ -621,14 +622,6 @@ bool LinkdefReader::ProcessOperators(std::string& pattern) return true; } -void LinkdefReader::SetIOCtorTypeCallback(IOCtorTypeCallback callback) -{ - // Set the callback function to be call for every - // #pragma link C++ ioctortype typename; - - fIOCtorTypeCallback = callback; -} - class LinkdefReaderPragmaHandler : public clang::PragmaHandler { protected: LinkdefReader &fOwner; diff --git a/core/utils/src/LinkdefReader.h b/core/utils/src/LinkdefReader.h index 57829e8ba9b81ec88def0c1eb695f3147bc895aa..46ca8b99c62a745853534f527eefb17d0020ce21 100644 --- a/core/utils/src/LinkdefReader.h +++ b/core/utils/src/LinkdefReader.h @@ -26,6 +26,8 @@ #include <map> #include "llvm/ADT/StringRef.h" +#include "TMetaUtils.h" + namespace cling { class Interpreter; } @@ -38,16 +40,28 @@ class PragmaExtraInclude; class LinkdefReader { + public: - typedef void (*IOCtorTypeCallback)(const char *type, const cling::Interpreter &interp); + LinkdefReader(cling::Interpreter &interp, + ROOT::TMetaUtils::RConstructorTypes& IOConstructorTypes); + + bool LoadIncludes(std::string &extraInclude); + bool Parse(SelectionRules& sr, llvm::StringRef code, const std::vector<std::string> &parserArgs, const char *llvmdir); + + private: + + friend class PragmaCreateCollector; + friend class PragmaLinkCollector; + friend class LinkdefReaderPragmaHandler; + friend class PragmaExtraInclude; + long fLine; // lines count - for error messages long fCount; // Number of rules created so far. SelectionRules *fSelectionRules; // set of rules being filleed. std::string fIncludes; // Extra set of file to be included by the intepreter. - IOCtorTypeCallback fIOCtorTypeCallback; // List of values of #pragma ioctortype + ROOT::TMetaUtils::RConstructorTypes* fIOConstructorTypesPtr; // List of values of #pragma ioctortype cling::Interpreter &fInterp; // Our interpreter -private: enum EPragmaNames { // the processed pragma attributes kAll, @@ -78,21 +92,7 @@ private: // used to create string to tag kind association to use in switch constructions static std::map<std::string, EPragmaNames> fgMapPragmaNames; static std::map<std::string, ECppNames> fgMapCppNames; - - friend class PragmaCreateCollector; - friend class PragmaLinkCollector; - friend class LinkdefReaderPragmaHandler; - friend class PragmaExtraInclude; - -public: - LinkdefReader(cling::Interpreter &interp); - - bool LoadIncludes(std::string &extraInclude); - void SetIOCtorTypeCallback(IOCtorTypeCallback callback); - - bool Parse(SelectionRules& sr, llvm::StringRef code, const std::vector<std::string> &parserArgs, const char *llvmdir); -private: static void PopulatePragmaMap(); static void PopulateCppMap(); diff --git a/core/utils/src/rootcling.cxx b/core/utils/src/rootcling.cxx index f94df6f5e2671f393fe33e23f4c73a345dffcda9..ea2283207baedde8c6a78b9e4358ee53a40fe80a 100644 --- a/core/utils/src/rootcling.cxx +++ b/core/utils/src/rootcling.cxx @@ -2689,6 +2689,7 @@ int GenerateFullDict(std::ostream& dictStream, cling::Interpreter& interp, RScanner& scan, SelectionRules& selectionRules, + const ROOT::TMetaUtils::RConstructorTypes& ctorTypes, bool onepcm, bool interpreteronly, bool isSplit, @@ -2715,13 +2716,6 @@ int GenerateFullDict(std::ostream& dictStream, // if (!interpreteronly){ - - // The order of addition to the list of constructor type - // is significant. The list is sorted by with the highest - // priority first. - ROOT::TMetaUtils::AddConstructorType("TRootIOCtor", interp); - ROOT::TMetaUtils::AddConstructorType("", interp); - // // Loop over all classes and create Streamer() & Showmembers() methods // @@ -2759,7 +2753,7 @@ int GenerateFullDict(std::ostream& dictStream, // coverity[fun_call_w_exception] - that's just fine. RStl::Instance().GenerateTClassFor( iter->GetNormalizedName(), CRD, interp, normCtxt); } else { - ROOT::TMetaUtils::WriteClassInit(dictStream, *iter, CRD, interp, normCtxt, needsCollectionProxy); + ROOT::TMetaUtils::WriteClassInit(dictStream, *iter, CRD, interp, normCtxt, ctorTypes, needsCollectionProxy); } } } @@ -2812,7 +2806,7 @@ int GenerateFullDict(std::ostream& dictStream, const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl()); if (!ROOT::TMetaUtils::IsSTLContainer(*iter)) { - ROOT::TMetaUtils::WriteClassInit(dictStream, *iter, CRD, interp, normCtxt, needsCollectionProxy); + ROOT::TMetaUtils::WriteClassInit(dictStream, *iter, CRD, interp, normCtxt, ctorTypes, needsCollectionProxy); } } // Loop to write all the ClassCode @@ -2825,6 +2819,7 @@ int GenerateFullDict(std::ostream& dictStream, interp, normCtxt, dictStream, + ctorTypes, isGenreflex); } } @@ -2844,7 +2839,7 @@ int GenerateFullDict(std::ostream& dictStream, if (!interpreteronly){ // coverity[fun_call_w_exception] - that's just fine. - ROOT::RStl::Instance().WriteClassInit(dictStream, interp, normCtxt, needsCollectionProxy); + ROOT::RStl::Instance().WriteClassInit(dictStream, interp, normCtxt, ctorTypes, needsCollectionProxy); } return 0; @@ -3557,6 +3552,8 @@ int RootCling(int argc, SelectionRules selectionRules(interp); std::string extraIncludes; + ROOT::TMetaUtils::RConstructorTypes constructorTypes; + bool isSelXML = IsSelectionXml(linkdefFilename.c_str()); if (requestAllSymbols && !isSelXML) { @@ -3565,8 +3562,7 @@ int RootCling(int argc, // There is no linkdef file, we added the 'default' #pragma to // interpPragmaSource. - LinkdefReader ldefr(interp); - ldefr.SetIOCtorTypeCallback(ROOT::TMetaUtils::AddConstructorType); + LinkdefReader ldefr(interp,constructorTypes); clingArgs.push_back("-Ietc/cling/cint"); // For multiset and multimap if (!ldefr.Parse(selectionRules, interpPragmaSource, clingArgs, @@ -3616,8 +3612,7 @@ int RootCling(int argc, selectionRules.SetSelectionFileType(SelectionRules::kLinkdefFile); - LinkdefReader ldefr(interp); - ldefr.SetIOCtorTypeCallback(ROOT::TMetaUtils::AddConstructorType); + LinkdefReader ldefr(interp,constructorTypes); clingArgs.push_back("-Ietc/cling/cint"); // For multiset and multimap if (!ldefr.Parse(selectionRules, interpPragmaSource, clingArgs, @@ -3713,11 +3708,20 @@ int RootCling(int argc, GenerateNecessaryIncludes(splitDictStream,includeForSource,extraIncludes); } } + + if (!onepcm && !interpreteronly){ + // The order of addition to the list of constructor type + // is significant. The list is sorted by with the highest + // priority first. + constructorTypes.push_back(ROOT::TMetaUtils::RConstructorType("TRootIOCtor", interp)); + constructorTypes.push_back(ROOT::TMetaUtils::RConstructorType("", interp)); + } int retCode = GenerateFullDict(splitDictStream, interp, scan, selectionRules, + constructorTypes, onepcm, interpreteronly, doSplit,