// @(#)root/metautils:$Id$ // Author: Axel Naumann, Nov 2011 /************************************************************************* * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TMetaUtils #define ROOT_TMetaUtils #include "RConversionRuleParser.h" #include #include #include //#include #include namespace llvm { class StringRef; } namespace clang { class ASTContext; class Attr; class ClassTemplateDecl; class ClassTemplateSpecializationDecl; class CompilerInstance; class CXXBaseSpecifier; class CXXRecordDecl; class Decl; class DeclContext; class DeclaratorDecl; class FieldDecl; class FunctionDecl; class Module; class NamedDecl; class ParmVarDecl; class PresumedLoc; class QualType; class RecordDecl; class SourceLocation; class TagDecl; class TemplateDecl; class TemplateName; class TemplateArgument; class TemplateArgumentList; class TemplateParameterList; class Type; class TypeDecl; class TypedefNameDecl; struct PrintingPolicy; } namespace cling { class Interpreter; class LookupHelper; namespace utils { namespace Transform { struct Config; } } } // For ROOT::ESTLType #include "ESTLType.h" // for TClassEdit::TInterpreterLookupHelper #include "TClassEdit.h" #ifndef ROOT_Varargs #include "Varargs.h" #endif namespace ROOT { namespace TMetaUtils { // Forward Declarations -------------------------------------------------------- class AnnotatedRecordDecl; // Constants, typedefs and Enums ----------------------------------------------- // Convention for the ROOT relevant properties namespace propNames{ static const std::string separator("@@@"); static const std::string iotype("iotype"); static const std::string name("name"); static const std::string pattern("pattern"); static const std::string ioname("ioname"); static const std::string comment("comment"); static const std::string nArgsToKeep("nArgsToKeep"); static const std::string persistent("persistent"); static const std::string transient("transient"); } extern int gErrorIgnoreLevel; // Get the array index information for a data member. enum DataMemberInfo__ValidArrayIndex_error_code { VALID, NOT_INT, NOT_DEF, IS_PRIVATE, UNKNOWN }; typedef void (*CallWriteStreamer_t)(const AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, std::ostream& dictStream, bool isAutoStreamer); const int kInfo = 0; const int kNote = 500; const int kThrowOnWarning = 999; const int kWarning = 1000; const int kError = 2000; const int kSysError = 3000; const int kFatal = 4000; const int kMaxLen = 1024; // Classes --------------------------------------------------------------------- class TNormalizedCtxtImpl; //______________________________________________________________________________ class TNormalizedCtxt { private: TNormalizedCtxtImpl* fImpl; public: using Config_t = cling::utils::Transform::Config; using TypesCont_t = std::set; using TemplPtrIntMap_t = std::map; TNormalizedCtxt(const cling::LookupHelper &lh); TNormalizedCtxt(const TNormalizedCtxt& other); ~TNormalizedCtxt(); const Config_t& GetConfig() const; const TypesCont_t &GetTypeWithAlternative() const; void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl* templ, unsigned int i); int GetNargsToKeep(const clang::ClassTemplateDecl* templ) const; const TemplPtrIntMap_t GetTemplNargsToKeepMap() const; void keepTypedef(const cling::LookupHelper &lh, const char* name, bool replace = false); }; //______________________________________________________________________________ class TClingLookupHelper : public TClassEdit::TInterpreterLookupHelper { public: typedef bool (*ExistingTypeCheck_t)(const std::string &tname, std::string &result); typedef bool (*AutoParse_t)(const char *name); private: cling::Interpreter *fInterpreter; TNormalizedCtxt *fNormalizedCtxt; ExistingTypeCheck_t fExistingTypeCheck; AutoParse_t fAutoParse; const int *fPDebug; // debug flag, might change at runtime thus * bool WantDiags() const { return fPDebug && *fPDebug > 5; } public: TClingLookupHelper(cling::Interpreter &interpreter, TNormalizedCtxt &normCtxt, ExistingTypeCheck_t existingTypeCheck, AutoParse_t autoParse, const int *pgDebug = 0); virtual ~TClingLookupHelper() { /* we're not owner */ } virtual bool ExistingTypeCheck(const std::string &tname, std::string &result); virtual void GetPartiallyDesugaredName(std::string &nameLong); virtual bool IsAlreadyPartiallyDesugaredName(const std::string &nondef, const std::string &nameLong); virtual bool IsDeclaredScope(const std::string &base, bool &isInlined); virtual bool GetPartiallyDesugaredNameWithScopeHandling(const std::string &tname, std::string &result); }; //______________________________________________________________________________ class AnnotatedRecordDecl { private: long fRuleIndex; const clang::RecordDecl* fDecl; std::string fRequestedName; std::string fNormalizedName; bool fRequestStreamerInfo; bool fRequestNoStreamer; bool fRequestNoInputOperator; bool fRequestOnlyTClass; int fRequestedVersionNumber; public: enum ERootFlag { kNoStreamer = 0x01, kNoInputOperator = 0x02, kUseByteCount = 0x04, kStreamerInfo = 0x04, kHasVersion = 0x08 }; AnnotatedRecordDecl(long index, const clang::RecordDecl *decl, bool rStreamerInfo, bool rNoStreamer, bool rRequestNoInputOperator, bool rRequestOnlyTClass, int rRequestedVersionNumber, const cling::Interpreter &interpret, const TNormalizedCtxt &normCtxt); AnnotatedRecordDecl(long index, const clang::RecordDecl *decl, const char *requestName, bool rStreamerInfo, bool rNoStreamer, bool rRequestNoInputOperator, bool rRequestOnlyTClass, int rRequestedVersionNumber, const cling::Interpreter &interpret, const TNormalizedCtxt &normCtxt); AnnotatedRecordDecl(long index, const clang::Type *requestedType, const clang::RecordDecl *decl, const char *requestedName, bool rStreamerInfo, bool rNoStreamer, bool rRequestNoInputOperator, bool rRequestOnlyTClass, int rRequestedVersionNumber, const cling::Interpreter &interpret, const TNormalizedCtxt &normCtxt); AnnotatedRecordDecl(long index, const clang::Type *requestedType, const clang::RecordDecl *decl, const char *requestedName, unsigned int nTemplateArgsToSkip, bool rStreamerInfo, bool rNoStreamer, bool rRequestNoInputOperator, bool rRequestOnlyTClass, int rRequestedVersionNumber, const cling::Interpreter &interpret, const TNormalizedCtxt &normCtxt); ~AnnotatedRecordDecl() { // Nothing to do we do not own the pointer; } long GetRuleIndex() const { return fRuleIndex; } const char *GetRequestedName() const { return fRequestedName.c_str(); } const char *GetNormalizedName() const { return fNormalizedName.c_str(); } bool HasClassVersion() const { return fRequestedVersionNumber >=0 ; } bool RequestStreamerInfo() const { // Equivalent to CINT's cl.RootFlag() & G__USEBYTECOUNT return fRequestStreamerInfo; } bool RequestNoInputOperator() const { return fRequestNoInputOperator; } bool RequestNoStreamer() const { return fRequestNoStreamer; } bool RequestOnlyTClass() const { return fRequestOnlyTClass; } int RequestedVersionNumber() const { return fRequestedVersionNumber; } int RootFlag() const { // Return the request (streamerInfo, has_version, etc.) combined in a single // int. See RScanner::AnnotatedRecordDecl::ERootFlag. int result = 0; if (fRequestNoStreamer) result = kNoStreamer; if (fRequestNoInputOperator) result |= kNoInputOperator; if (fRequestStreamerInfo) result |= kStreamerInfo; if (fRequestedVersionNumber > -1) result |= kHasVersion; return result; } const clang::RecordDecl* GetRecordDecl() const { return fDecl; } operator clang::RecordDecl const *() const { return fDecl; } bool operator<(const AnnotatedRecordDecl& right) const { return fRuleIndex < right.fRuleIndex; } struct CompareByName { bool operator() (const AnnotatedRecordDecl& right, const AnnotatedRecordDecl& left) { return left.fNormalizedName < right.fNormalizedName; } }; }; //______________________________________________________________________________ class RConstructorType { private: const std::string fArgTypeName; const clang::CXXRecordDecl *fArgType; public: RConstructorType(const char *type_of_arg, const cling::Interpreter&); const char *GetName() const ; const clang::CXXRecordDecl *GetType() const; }; typedef std::list RConstructorTypes; // Functions ------------------------------------------------------------------- //_____________________________________________________________________________ unsigned int GetNumberOfWarningsAndErrors(); //______________________________________________________________________________ int extractAttrString(clang::Attr* attribute, std::string& attrString); //______________________________________________________________________________ int extractPropertyNameValFromString(const std::string attributeStr,std::string& attrName, std::string& attrValue); //______________________________________________________________________________ int extractPropertyNameVal(clang::Attr* attribute, std::string& attrName, std::string& attrValue); //______________________________________________________________________________ bool ExtractAttrPropertyFromName(const clang::Decl& decl, const std::string& propName, std::string& propValue); //______________________________________________________________________________ bool ExtractAttrIntPropertyFromName(const clang::Decl& decl, const std::string& propName, int& propValue); //______________________________________________________________________________ bool RequireCompleteType(const cling::Interpreter &interp, const clang::CXXRecordDecl *cl); //______________________________________________________________________________ bool RequireCompleteType(const cling::Interpreter &interp, clang::SourceLocation Loc, clang::QualType Type); //______________________________________________________________________________ // Add default template parameters. clang::QualType AddDefaultParameters(clang::QualType instanceType, const cling::Interpreter &interpret, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ llvm::StringRef DataMemberInfo__ValidArrayIndex(const clang::DeclaratorDecl &m, int *errnum = 0, llvm::StringRef *errstr = 0); //______________________________________________________________________________ // Return the ROOT include directory std::string GetROOTIncludeDir(bool rootbuild); enum class EIOCtorCategory : short {kAbsent, kDefault, kIOPtrType, kIORefType}; //______________________________________________________________________________ EIOCtorCategory CheckConstructor(const clang::CXXRecordDecl*, const RConstructorType&, const cling::Interpreter& interp); //______________________________________________________________________________ const clang::FunctionDecl* ClassInfo__HasMethod(const clang::DeclContext *cl, char const*, const cling::Interpreter& interp); //______________________________________________________________________________ void CreateNameTypeMap(clang::CXXRecordDecl const&, std::map, std::allocator > >&); //______________________________________________________________________________ int ElementStreamer(std::ostream& finalString, const clang::NamedDecl &forcontext, const clang::QualType &qti, const char *t, int rwmode, const cling::Interpreter &interp, const char *tcl=0); //______________________________________________________________________________ bool IsBase(const clang::CXXRecordDecl *cl, const clang::CXXRecordDecl *base, const clang::CXXRecordDecl *context,const cling::Interpreter &interp); //______________________________________________________________________________ bool IsBase(const clang::FieldDecl &m, const char* basename, const cling::Interpreter &interp); //______________________________________________________________________________ bool HasCustomOperatorNewArrayPlacement(clang::RecordDecl const&, const cling::Interpreter &interp); //______________________________________________________________________________ bool HasCustomOperatorNewPlacement(char const*, clang::RecordDecl const&, const cling::Interpreter&); //______________________________________________________________________________ bool HasCustomOperatorNewPlacement(clang::RecordDecl const&, const cling::Interpreter&); //______________________________________________________________________________ bool HasDirectoryAutoAdd(clang::CXXRecordDecl const*, const cling::Interpreter&); //______________________________________________________________________________ bool HasIOConstructor(clang::CXXRecordDecl const*, std::string&, const RConstructorTypes&, const cling::Interpreter&); //______________________________________________________________________________ bool HasNewMerge(clang::CXXRecordDecl const*, const cling::Interpreter&); //______________________________________________________________________________ bool HasOldMerge(clang::CXXRecordDecl const*, const cling::Interpreter&); //______________________________________________________________________________ bool hasOpaqueTypedef(clang::QualType instanceType, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ bool hasOpaqueTypedef(const AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ bool HasResetAfterMerge(clang::CXXRecordDecl const*, const cling::Interpreter&); //______________________________________________________________________________ bool NeedDestructor(clang::CXXRecordDecl const*); //______________________________________________________________________________ bool NeedTemplateKeyword(clang::CXXRecordDecl const*); //______________________________________________________________________________ bool CheckPublicFuncWithProto(clang::CXXRecordDecl const*, char const*, char const*, const cling::Interpreter&, bool diagnose); //______________________________________________________________________________ long GetLineNumber(clang::Decl const*); //______________________________________________________________________________ bool GetNameWithinNamespace(std::string&, std::string&, std::string&, clang::CXXRecordDecl const*); //______________________________________________________________________________ void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext); //---- std::string GetQualifiedName(const clang::QualType &type, const clang::NamedDecl &forcontext); //______________________________________________________________________________ void GetQualifiedName(std::string &qual_name, const clang::Type &type, const clang::NamedDecl &forcontext); //---- std::string GetQualifiedName(const clang::Type &type, const clang::NamedDecl &forcontext); //______________________________________________________________________________ void GetQualifiedName(std::string &qual_name, const clang::NamedDecl &nd); //---- std::string GetQualifiedName(const clang::NamedDecl &nd); //______________________________________________________________________________ void GetQualifiedName(std::string &qual_name, const AnnotatedRecordDecl &annotated); //---- std::string GetQualifiedName(const AnnotatedRecordDecl &annotated); //______________________________________________________________________________ void GetQualifiedName(std::string &qual_name, const clang::RecordDecl &recordDecl); //---- std::string GetQualifiedName(const clang::RecordDecl &recordDecl); //______________________________________________________________________________ int WriteNamespaceHeader(std::ostream&, const clang::RecordDecl *); //______________________________________________________________________________ int WriteNamespaceHeader(std::ostream&, const clang::DeclContext *); //______________________________________________________________________________ void WritePointersSTL(const AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp); //______________________________________________________________________________ int IsSTLContainer(const AnnotatedRecordDecl &annotated); //______________________________________________________________________________ ROOT::ESTLType IsSTLContainer(const clang::FieldDecl &m); //______________________________________________________________________________ int IsSTLContainer(const clang::CXXBaseSpecifier &base); //______________________________________________________________________________ const char *ShortTypeName(const char *typeDesc); //______________________________________________________________________________ std::string ShortTypeName(const clang::FieldDecl &m); //______________________________________________________________________________ bool IsStreamableObject(const clang::FieldDecl &m, const cling::Interpreter& interp); //______________________________________________________________________________ clang::RecordDecl *GetUnderlyingRecordDecl(clang::QualType type); //______________________________________________________________________________ std::string TrueName(const clang::FieldDecl &m); //______________________________________________________________________________ const clang::CXXRecordDecl *ScopeSearch(const char *name, const cling::Interpreter &gInterp, bool diagnose, const clang::Type** resultType); //______________________________________________________________________________ void WriteAuxFunctions(std::ostream& finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const RConstructorTypes& ctorTypes, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ const clang::FunctionDecl *GetFuncWithProto(const clang::Decl* cinfo, const char *method, const char *proto, const cling::Interpreter &gInterp, bool diagnose); //______________________________________________________________________________ void WriteClassCode(CallWriteStreamer_t WriteStreamerFunc, const AnnotatedRecordDecl &cl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, std::ostream& finalString, const RConstructorTypes& ctorTypes, bool isGenreflex); //______________________________________________________________________________ void WriteClassInit(std::ostream& finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, const RConstructorTypes& ctorTypes, bool& needCollectionProxy); //______________________________________________________________________________ bool HasCustomStreamerMemberFunction(const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl* clxx, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ bool HasCustomConvStreamerMemberFunction(const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl* clxx, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ // Return the header file to be included to declare the Decl llvm::StringRef GetFileName(const clang::Decl& decl, const cling::Interpreter& interp); //______________________________________________________________________________ // Return the dictionary file name for a module std::string GetModuleFileName(const char* moduleName); //______________________________________________________________________________ // Declare a virtual module.map to clang. Returns Module on success. clang::Module* declareModuleMap(clang::CompilerInstance* CI, const char* moduleFileName, const char* headers[]); //______________________________________________________________________________ // Return the -I needed to find RuntimeUniverse.h std::string GetInterpreterExtraIncludePath(bool rootbuild); //______________________________________________________________________________ // Return the LLVM / clang resource directory std::string GetLLVMResourceDir(bool rootbuild); //______________________________________________________________________________ // Return the ROOT include directory std::string GetROOTIncludeDir(bool rootbuild); //______________________________________________________________________________ // Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') // that can be used in C++ as a variable name. void GetCppName(std::string &output, const char *input); //______________________________________________________________________________ // Return the type with all parts fully qualified (most typedefs), // including template arguments, appended to name. void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const cling::Interpreter &interpreter); //______________________________________________________________________________ // Return the type with all parts fully qualified (most typedefs), // including template arguments, appended to name, without using the interpreter void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const clang::ASTContext &); //______________________________________________________________________________ // Return the type normalized for ROOT, // keeping only the ROOT opaque typedef (Double32_t, etc.) and // adding default template argument for all types except those explicitly // requested to be drop by the user. // Default template for STL collections are not yet removed by this routine. clang::QualType GetNormalizedType(const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ // Return the type name normalized for ROOT, // keeping only the ROOT opaque typedef (Double32_t, etc.) and // adding default template argument for all types except the STL collections // where we remove the default template argument if any. void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt); //______________________________________________________________________________ // Alternative signature void GetNormalizedName(std::string &norm_name, const clang::TypeDecl* typeDecl, const cling::Interpreter &interpreter); //______________________________________________________________________________ // Returns comment in a meaningful way llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc = 0); //______________________________________________________________________________ // Returns the comment of the ClassDef macro llvm::StringRef GetClassComment(const clang::CXXRecordDecl &decl, clang::SourceLocation *loc, const cling::Interpreter &interpreter); //______________________________________________________________________________ // Return the base/underlying type of a chain of array or pointers type. const clang::Type *GetUnderlyingType(clang::QualType type); //______________________________________________________________________________ // Scans the redeclaration chain for an annotation. // // returns 0 if no annotation was found. // template const T* GetAnnotatedRedeclarable(const T* Redecl) { if (!Redecl) return 0; Redecl = Redecl->getMostRecentDecl(); while (Redecl && !Redecl->hasAttrs()) Redecl = Redecl->getPreviousDecl(); return Redecl; } //______________________________________________________________________________ // Overload the template for typedefs, because they don't contain // isThisDeclarationADefinition method. (Use inline to avoid violating ODR) const clang::TypedefNameDecl* GetAnnotatedRedeclarable(const clang::TypedefNameDecl* TND); //______________________________________________________________________________ // Overload the template for tags, because we only check definitions. const clang::TagDecl* GetAnnotatedRedeclarable(const clang::TagDecl* TND); //______________________________________________________________________________ // Return true if the decl is part of the std namespace. bool IsStdClass(const clang::RecordDecl &cl); //______________________________________________________________________________ // Return true, if the decl is part of the std namespace and we want // its default parameter dropped. bool IsStdDropDefaultClass(const clang::RecordDecl &cl); //______________________________________________________________________________ // See if the CXXRecordDecl matches the current of any of the previous CXXRecordDecls bool MatchWithDeclOrAnyOfPrevious(const clang::CXXRecordDecl &cl, const clang::CXXRecordDecl ¤tCl); //______________________________________________________________________________ // Return true if the decl is of type bool IsOfType(const clang::CXXRecordDecl &cl, const std::string& type, const cling::LookupHelper& lh); //______________________________________________________________________________ // Return which kind of STL container the decl is, if any. ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl); //______________________________________________________________________________ // Check if 'input' or any of its template parameter was substituted when // instantiating the class template instance and replace it with the // partially sugared type we have from 'instance'. clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance); //______________________________________________________________________________ // Remove the last n template arguments from the name int RemoveTemplateArgsFromName(std::string& name, unsigned int); //______________________________________________________________________________ clang::TemplateName ExtractTemplateNameFromQualType(const clang::QualType& qt); //______________________________________________________________________________ bool QualType2Template(const clang::QualType& qt, clang::ClassTemplateDecl*& ctd, clang::ClassTemplateSpecializationDecl*& ctsd); //______________________________________________________________________________ clang::ClassTemplateDecl* QualType2ClassTemplateDecl(const clang::QualType& qt); //______________________________________________________________________________ // Extract the namespaces enclosing a DeclContext void ExtractCtxtEnclosingNameSpaces(const clang::DeclContext&, std::list >&); //______________________________________________________________________________ void ExtractEnclosingNameSpaces(const clang::Decl&, std::list >&); //______________________________________________________________________________ const clang::RecordDecl* ExtractEnclosingScopes(const clang::Decl& decl, std::list >& enclosingSc); //______________________________________________________________________________ // Kind of stl container ROOT::ESTLType STLKind(const llvm::StringRef type); //______________________________________________________________________________ // Set the toolchain and the include paths for relocatability void SetPathsForRelocatability(std::vector& clingArgs); //______________________________________________________________________________ void ReplaceAll(std::string& str, const std::string& from, const std::string& to, bool recurse=false); // Functions for the printouts ------------------------------------------------- //______________________________________________________________________________ void LevelPrint(bool prefix, int level, const char *location, const char *fmt, va_list ap); //______________________________________________________________________________ void Error(const char *location, const char *va_(fmt), ...); //______________________________________________________________________________ void SysError(const char *location, const char *va_(fmt), ...); //______________________________________________________________________________ void Info(const char *location, const char *va_(fmt), ...); //______________________________________________________________________________ void Warning(const char *location, const char *va_(fmt), ...); //______________________________________________________________________________ void Fatal(const char *location, const char *va_(fmt), ...); //______________________________________________________________________________ const std::string& GetPathSeparator(); //______________________________________________________________________________ bool EndsWith(const std::string &theString, const std::string &theSubstring); //______________________________________________________________________________ bool BeginsWith(const std::string &theString, const std::string &theSubstring); //______________________________________________________________________________ namespace AST2SourceTools { //______________________________________________________________________________ const std::string Decls2FwdDecls(const std::vector &decls, bool (*ignoreFiles)(const clang::PresumedLoc&) , const cling::Interpreter& interp); //______________________________________________________________________________ int PrepareArgsForFwdDecl(std::string& templateArgs, const clang::TemplateParameterList& tmplParamList, const cling::Interpreter& interpreter); //______________________________________________________________________________ int EncloseInNamespaces(const clang::Decl& decl, std::string& defString); //______________________________________________________________________________ const clang::RecordDecl* EncloseInScopes(const clang::Decl& decl, std::string& defString); //______________________________________________________________________________ int FwdDeclFromRcdDecl(const clang::RecordDecl& recordDecl, const cling::Interpreter& interpreter, std::string& defString, bool acceptStl=false); //______________________________________________________________________________ int FwdDeclFromTmplDecl(const clang::TemplateDecl& tmplDecl, const cling::Interpreter& interpreter, std::string& defString); //______________________________________________________________________________ int GetDefArg(const clang::ParmVarDecl& par, std::string& valAsString, const clang::PrintingPolicy& pp); //______________________________________________________________________________ int FwdDeclFromFcnDecl(const clang::FunctionDecl& fcnDecl, const cling::Interpreter& interpreter, std::string& defString); //______________________________________________________________________________ int FwdDeclFromTypeDefNameDecl(const clang::TypedefNameDecl& tdnDecl, const cling::Interpreter& interpreter, std::string& fwdDeclString, std::unordered_set* fwdDeclSet=nullptr); } // namespace AST2SourceTools } // namespace TMetaUtils } // namespace ROOT #endif // ROOT_TMetaUtils