24 #include <unordered_set> 26 #include "RConfigure.h" 29 #include "compiledata.h" 33 #include "clang/AST/ASTContext.h" 34 #include "clang/AST/Attr.h" 35 #include "clang/AST/CXXInheritance.h" 36 #include "clang/AST/Decl.h" 37 #include "clang/AST/DeclTemplate.h" 38 #include "clang/AST/Type.h" 39 #include "clang/AST/TypeVisitor.h" 40 #include "clang/Frontend/CompilerInstance.h" 41 #include "clang/Lex/HeaderSearch.h" 42 #include "clang/Lex/ModuleMap.h" 43 #include "clang/Lex/Preprocessor.h" 45 #include "clang/Sema/Sema.h" 46 #include "clang/Sema/SemaDiagnostic.h" 48 #include "cling/Interpreter/LookupHelper.h" 49 #include "cling/Interpreter/Transaction.h" 50 #include "cling/Interpreter/Interpreter.h" 51 #include "cling/Utils/AST.h" 53 #include "llvm/Support/Path.h" 54 #include "llvm/Support/FileSystem.h" 57 #include "../../../interpreter/llvm/src/tools/clang/lib/Sema/HackForDefaultTemplateArg.h" 62 namespace TMetaUtils {
66 class TNormalizedCtxtImpl {
67 using DeclsCont_t = TNormalizedCtxt::Config_t::SkipCollection;
73 TypesCont_t fTypeWithAlternative;
74 static TemplPtrIntMap_t fTemplatePtrArgsToKeepMap;
76 TNormalizedCtxtImpl(
const cling::LookupHelper &lh);
78 const Config_t &GetConfig()
const {
return fConfig; }
79 const TypesCont_t &GetTypeWithAlternative()
const {
return fTypeWithAlternative; }
80 void AddTemplAndNargsToKeep(
const clang::ClassTemplateDecl* templ,
unsigned int i);
81 int GetNargsToKeep(
const clang::ClassTemplateDecl* templ)
const;
82 const TemplPtrIntMap_t GetTemplNargsToKeepMap()
const {
return fTemplatePtrArgsToKeepMap; }
83 void keepTypedef(
const cling::LookupHelper &lh,
const char*
name,
84 bool replace =
false);
94 static clang::NestedNameSpecifier* AddDefaultParametersNNS(
const clang::ASTContext& Ctx,
95 clang::NestedNameSpecifier* scope,
96 const cling::Interpreter &interpreter,
100 const clang::Type* scope_type = scope->getAsType();
103 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
105 outer_scope = AddDefaultParametersNNS(Ctx, outer_scope, interpreter, normCtxt);
108 clang::QualType addDefault =
111 if (addDefault.getTypePtr() != scope_type)
112 return clang::NestedNameSpecifier::Create(Ctx,outer_scope,
114 addDefault.getTypePtr());
121 static bool CheckDefinition(
const clang::CXXRecordDecl *cl,
const clang::CXXRecordDecl *context)
123 if (!cl->hasDefinition()) {
126 "Missing definition for class %s, please #include its header in the header of %s\n",
127 cl->getName().str().c_str(), context->getName().str().c_str());
130 "Missing definition for class %s\n",
131 cl->getName().str().c_str());
143 static clang::NestedNameSpecifier* ReSubstTemplateArgNNS(
const clang::ASTContext &Ctxt,
144 clang::NestedNameSpecifier *scope,
147 if (!scope)
return 0;
149 const clang::Type* scope_type = scope->getAsType();
151 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
153 outer_scope = ReSubstTemplateArgNNS(Ctxt, outer_scope, instance);
155 clang::QualType substScope =
158 scope = clang::NestedNameSpecifier::Create(Ctxt,outer_scope,
160 substScope.getTypePtr());
169 const clang::BuiltinType * builtin = llvm::dyn_cast<clang::BuiltinType>(type->getCanonicalTypeInternal().getTypePtr());
171 return builtin->isInteger();
179 static bool IsFieldDeclInt(
const clang::FieldDecl *field)
181 return IsTypeInt(field->getType().getTypePtr());
187 static const clang::FieldDecl *GetDataMemberFromAll(
const clang::CXXRecordDecl &cl, llvm::StringRef
what)
189 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
192 if (field_iter->getName() ==
what) {
202 static bool CXXRecordDecl__FindOrdinaryMember(
const clang::CXXBaseSpecifier *Specifier,
203 clang::CXXBasePath &Path,
206 clang::RecordDecl *BaseRecord = Specifier->getType()->getAs<clang::RecordType>()->getDecl();
208 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(BaseRecord);
209 if (clxx == 0)
return false;
211 const clang::FieldDecl *found = GetDataMemberFromAll(*clxx,(
const char*)Name);
215 clang::NamedDecl* NonConstFD =
const_cast<clang::FieldDecl*
>(found);
216 clang::NamedDecl** BaseSpecFirstHack
217 =
reinterpret_cast<clang::NamedDecl**
>(NonConstFD);
218 Path.Decls = clang::DeclContextLookupResult(llvm::ArrayRef<clang::NamedDecl*>(BaseSpecFirstHack, 1));
243 static const clang::FieldDecl *GetDataMemberFromAllParents(
const clang::CXXRecordDecl &cl,
const char *what)
245 clang::CXXBasePaths Paths;
246 Paths.setOrigin(const_cast<clang::CXXRecordDecl*>(&cl));
247 if (cl.lookupInBases([=](
const clang::CXXBaseSpecifier *Specifier, clang::CXXBasePath &Path) {
248 return CXXRecordDecl__FindOrdinaryMember(Specifier, Path, what);}, Paths))
250 clang::CXXBasePaths::paths_iterator iter = Paths.begin();
251 if (iter != Paths.end()) {
253 const clang::FieldDecl *found = (clang::FieldDecl *)iter->Decls.data();
261 cling::LookupHelper::DiagSetting ToLHDS(
bool wantDiags) {
263 ? cling::LookupHelper::WithDiagnostics
264 : cling::LookupHelper::NoDiagnostics;
271 namespace TMetaUtils {
277 void TNormalizedCtxtImpl::AddTemplAndNargsToKeep(
const clang::ClassTemplateDecl* templ,
280 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
281 "Tring to specify a number of template arguments to keep for a null pointer. Exiting without assigning any value.\n");
285 const clang::ClassTemplateDecl* canTempl = templ->getCanonicalDecl();
287 if(fTemplatePtrArgsToKeepMap.count(canTempl)==1 &&
288 fTemplatePtrArgsToKeepMap[canTempl]!=(int)i){
289 const std::string templateName (canTempl->getNameAsString());
290 const std::string i_str (std::to_string(i));
291 const std::string previousArgsToKeep(std::to_string(fTemplatePtrArgsToKeepMap[canTempl]));
292 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
293 "Tring to specify for template %s %s arguments to keep, while before this number was %s\n",
294 canTempl->getNameAsString().c_str(),
296 previousArgsToKeep.c_str());
299 fTemplatePtrArgsToKeepMap[canTempl]=i;
306 int TNormalizedCtxtImpl::GetNargsToKeep(
const clang::ClassTemplateDecl* templ)
const{
307 const clang::ClassTemplateDecl* constTempl = templ->getCanonicalDecl();
308 auto thePairPtr = fTemplatePtrArgsToKeepMap.find(constTempl);
309 int nArgsToKeep = (thePairPtr != fTemplatePtrArgsToKeepMap.end() ) ? thePairPtr->second : -1;
317 fImpl(new TNormalizedCtxtImpl(lh))
328 return fImpl->GetConfig();
331 return fImpl->GetTypeWithAlternative();
335 return fImpl->AddTemplAndNargsToKeep(templ, i);
339 return fImpl->GetNargsToKeep(templ);
342 return fImpl->GetTemplNargsToKeepMap();
347 return fImpl->keepTypedef(lh, name, replace);
357 const clang::RecordDecl *decl,
360 bool rRequestNoInputOperator,
361 bool rRequestOnlyTClass,
362 int rRequestedVersionNumber,
363 const cling::Interpreter &interpreter,
365 fRuleIndex(index), fDecl(decl), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
366 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestedVersionNumber)
377 const clang::RecordDecl *decl,
378 const char *requestName,
379 unsigned int nTemplateArgsToSkip,
382 bool rRequestNoInputOperator,
383 bool rRequestOnlyTClass,
384 int rRequestVersionNumber,
385 const cling::Interpreter &interpreter,
397 "Could not remove the requested template arguments.\n");
406 const clang::RecordDecl *decl,
407 const char *requestName,
410 bool rRequestNoInputOperator,
411 bool rRequestOnlyTClass,
412 int rRequestVersionNumber,
413 const cling::Interpreter &interpreter,
429 const clang::RecordDecl *decl,
430 const char *requestName,
433 bool rRequestNoInputOperator,
434 bool rRequestOnlyTClass,
435 int rRequestVersionNumber,
436 const cling::Interpreter &interpreter,
447 if (requestName && requestName[0]) {
463 ExistingTypeCheck_t existingTypeCheck,
464 AutoParse_t autoParse,
465 const int* pgDebug ):
466 fInterpreter(&interpreter),fNormalizedCtxt(&normCtxt),
467 fExistingTypeCheck(existingTypeCheck),
468 fAutoParse(autoParse), fPDebug(pgDebug)
479 if (tname.empty())
return false;
489 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
490 clang::QualType t = lh.findType(nameLong, ToLHDS(
WantDiags()));
493 if (!dest.isNull() && (dest != t)) {
496 dest.getAsStringInternal(nameLong,
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
504 const std::string &nameLong)
506 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
507 clang::QualType t = lh.findType(nondef.c_str(), ToLHDS(
WantDiags()));
510 if (!dest.isNull() && (dest != t) &&
511 nameLong == t.getAsString(
fInterpreter->getCI()->getASTContext().getPrintingPolicy()))
521 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
522 const clang::Decl *scope = lh.findScope(base.c_str(), ToLHDS(
WantDiags()), 0);
529 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(scope);
530 isInlined = nsdecl && nsdecl->isInline();
541 if (tname.empty())
return false;
549 return ! result.empty();
558 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
559 clang::QualType t = lh.findType(tname.c_str(), ToLHDS(
WantDiags()));
566 if (!dest.isNull() && dest != t) {
570 clang::PrintingPolicy policy(
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
571 policy.SuppressTagKeyword =
true;
572 policy.SuppressScope =
true;
578 dest.getAsStringInternal(result, policy);
580 unsigned long offset = 0;
581 if (strncmp(result.c_str(),
"const ", 6) == 0) {
584 if (strncmp(result.c_str()+offset,
"std::", 5) == 0) {
585 result.erase(offset,5);
587 for(
unsigned int i = 1; i<result.length(); ++i) {
588 if (result[i]==
's') {
589 if (result[i-1]==
'<' || result[i-1]==
',' || result[i-1]==
' ') {
590 if (result.compare(i,5,
"std::",5) == 0) {
595 if (result[i]==
' ') {
596 if (result[i-1] ==
',') {
599 }
else if ( (i+1) < result.length() &&
600 (result[i+1]==
'*' || result[i+1]==
'&' || result[i+1]==
'[') ) {
625 void ROOT::TMetaUtils::TNormalizedCtxtImpl::keepTypedef(
const cling::LookupHelper &lh,
628 clang::QualType toSkip = lh.findType(name, cling::LookupHelper::WithDiagnostics);
630 const clang::TypedefType *
tt = llvm::dyn_cast<clang::TypedefType>(
T);
632 clang::Decl* D = tt->getDecl();
633 fConfig.m_toSkip.insert(D);
635 clang::QualType canon = toSkip->getCanonicalTypeInternal();
636 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),
T));
638 fTypeWithAlternative.insert(
T);
649 ROOT::TMetaUtils::TNormalizedCtxtImpl::TNormalizedCtxtImpl(
const cling::LookupHelper &lh)
651 keepTypedef(lh,
"Double32_t");
652 keepTypedef(lh,
"Float16_t");
653 keepTypedef(lh,
"Long64_t",
true);
654 keepTypedef(lh,
"ULong64_t",
true);
656 clang::QualType toSkip = lh.findType(
"string", cling::LookupHelper::WithDiagnostics);
657 if (
const clang::TypedefType* TT
658 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
659 fConfig.m_toSkip.insert(TT->getDecl());
661 toSkip = lh.findType(
"std::string", cling::LookupHelper::WithDiagnostics);
662 if (!toSkip.isNull()) {
663 if (
const clang::TypedefType* TT
664 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
665 fConfig.m_toSkip.insert(TT->getDecl());
667 clang::QualType canon = toSkip->getCanonicalTypeInternal();
668 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),toSkip.getTypePtr()));
673 TNCtxtFullQual::TemplPtrIntMap_t TNCtxtFullQual::fTemplatePtrArgsToKeepMap=TNCtxtFullQual::TemplPtrIntMap_t{};
679 return (cl.getKind() == clang::Decl::ClassTemplatePartialSpecialization
680 || cl.getKind() == clang::Decl::ClassTemplateSpecialization);
687 const cling::Interpreter& interp)
689 clang::Sema*
S = &interp.getSema();
690 const clang::NamedDecl* ND = cling::utils::Lookup::Named(S, name, cl);
691 if (ND == (clang::NamedDecl*)-1)
692 return (clang::FunctionDecl*)-1;
693 return llvm::dyn_cast_or_null<clang::FunctionDecl>(ND);
699 const clang::CXXRecordDecl *
703 const cling::LookupHelper& lh = interp.getLookupHelper();
706 const clang::CXXRecordDecl *
result 707 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
708 (lh.findScope(name, cling::LookupHelper::NoDiagnostics, resultType));
710 std::string std_name(
"std::");
714 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
715 (lh.findScope(std_name, cling::LookupHelper::NoDiagnostics, resultType));
725 clang::QualType qType(cl->getTypeForDecl(),0);
733 clang::Sema&
S = interp.getCI()->getSema();
736 cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interp));
737 return S.RequireCompleteType(Loc, Type, clang::diag::err_incomplete_type);
743 const clang::CXXRecordDecl *context,
const cling::Interpreter &interp)
749 if (!cl->getDefinition() || !cl->isCompleteDefinition()) {
753 if (!CheckDefinition(cl, context) || !CheckDefinition(base, context)) {
757 if (!base->hasDefinition()) {
761 return cl->isDerivedFrom(base);
773 const clang::NamedDecl *base
777 return IsBase(CRD, llvm::dyn_cast<clang::CXXRecordDecl>( base ),
778 llvm::dyn_cast<clang::CXXRecordDecl>(m.getDeclContext()),interp);
786 const clang::NamedDecl &forcontext,
787 const clang::QualType &qti,
788 const char *R__t,
int rwmode,
789 const cling::Interpreter &interp,
792 static const clang::CXXRecordDecl *TObject_decl
795 kBIT_ISTOBJECT = 0x10000000,
796 kBIT_HASSTREAMER = 0x20000000,
797 kBIT_ISSTRING = 0x40000000,
799 kBIT_ISPOINTER = 0x00001000,
800 kBIT_ISFUNDAMENTAL = 0x00000020,
801 kBIT_ISENUM = 0x00000008
814 clang::CXXRecordDecl *cxxtype = rawtype->getAsCXXRecordDecl() ;
816 int isTObj = cxxtype && (
IsBase(cxxtype,TObject_decl,
nullptr,interp) || rawname ==
"TObject");
820 if (ti.isPointerType()) kase |= kBIT_ISPOINTER;
821 if (rawtype->isFundamentalType()) kase |= kBIT_ISFUNDAMENTAL;
822 if (rawtype->isEnumeralType()) kase |= kBIT_ISENUM;
825 if (isTObj) kase |= kBIT_ISTOBJECT;
826 if (isStre) kase |= kBIT_HASSTREAMER;
827 if (tiName ==
"string") kase |= kBIT_ISSTRING;
828 if (tiName ==
"string*") kase |= kBIT_ISSTRING;
832 tcl =
" internal error in rootcling ";
838 if (R__t) finalString <<
" " << tiName <<
" " << R__t <<
";" << std::endl;
841 case kBIT_ISFUNDAMENTAL:
843 finalString <<
" R__b >> " << R__t <<
";" << std::endl;
846 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
848 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
857 finalString <<
" Int_t readtemp;" << std::endl
858 <<
" R__b >> readtemp;" << std::endl
859 <<
" " << R__t <<
" = static_cast<" << tiName <<
">(readtemp);" << std::endl;
862 case kBIT_HASSTREAMER:
863 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
865 finalString <<
" " << R__t <<
".Streamer(R__b);" << std::endl;
868 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
871 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
872 if (cxxtype && cxxtype->isAbstract()) {
873 finalString <<
" R__ASSERT(0);// " << objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
875 finalString <<
" " << R__t <<
" = new " << objType <<
";" << std::endl
876 <<
" " << R__t <<
"->Streamer(R__b);" << std::endl;
878 finalString <<
" } else {" << std::endl
879 <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl
880 <<
" }" << std::endl;
885 finalString <<
" {TString R__str;" << std::endl
886 <<
" R__str.Streamer(R__b);" << std::endl
887 <<
" " << R__t <<
" = R__str.Data();}" << std::endl;
890 case kBIT_ISSTRING|kBIT_ISPOINTER:
892 finalString <<
" {TString R__str;" << std::endl
893 <<
" R__str.Streamer(R__b);" << std::endl
894 <<
" " << R__t <<
" = new string(R__str.Data());}" << std::endl;
899 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
904 finalString <<
" R__b.StreamObject(&" << R__t <<
"," << tcl <<
");" << std::endl;
912 case kBIT_ISFUNDAMENTAL:
913 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
915 finalString <<
" R__b << " << R__t <<
";" << std::endl;
920 finalString <<
" { void *ptr_enum = (void*)&" << R__t <<
";\n";
921 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
924 case kBIT_HASSTREAMER:
925 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
927 finalString <<
" ((" << objType <<
"&)" << R__t <<
").Streamer(R__b);" << std::endl;
930 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
932 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
937 finalString <<
" {TString R__str(" << R__t <<
".c_str());" << std::endl
938 <<
" R__str.Streamer(R__b);};" << std::endl;
941 case kBIT_ISSTRING|kBIT_ISPOINTER:
943 finalString <<
" {TString R__str(" << R__t <<
"->c_str());" << std::endl
944 <<
" R__str.Streamer(R__b);}" << std::endl;
949 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
954 finalString <<
" R__b.StreamObject((" << objType <<
"*)&" << R__t <<
"," << tcl <<
");" << std::endl;
965 const cling::Interpreter& interpreter)
967 const char *arg = ioctortype.
GetName();
969 if (ioctortype.
GetType() ==0 && (arg == 0 || arg[0] ==
'\0')) {
971 clang::CXXRecordDecl* ncCl =
const_cast<clang::CXXRecordDecl*
>(cl);
974 cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
976 if (
auto* Ctor = interpreter.getCI()->getSema().LookupDefaultConstructor(ncCl)) {
977 if (Ctor->getAccess() == clang::AS_public) {
984 for (clang::CXXRecordDecl::ctor_iterator iter = cl->ctor_begin(), end = cl->ctor_end();
988 if (iter->getAccess() != clang::AS_public)
992 if (iter->getNumParams() == 1) {
993 clang::QualType argType( (*iter->param_begin())->getType() );
994 argType = argType.getDesugaredType(cl->getASTContext());
997 if (argType->isPointerType()) {
999 argType = argType->getPointeeType();
1000 }
else if (argType->isReferenceType()){
1002 argType = argType.getNonReferenceType();
1005 argType = argType.getDesugaredType(cl->getASTContext());
1006 const clang::CXXRecordDecl *argDecl = argType->getAsCXXRecordDecl();
1007 if (argDecl && ioctortype.
GetType()) {
1008 if (argDecl->getCanonicalDecl() == ioctortype.
GetType()->getCanonicalDecl()) {
1009 return ioCtorCategory;
1012 std::string realArg = argType.getAsString();
1013 std::string clarg(
"class ");
1015 if (realArg == clarg) {
1016 return ioCtorCategory;
1031 const char *method,
const char *
proto,
1032 const cling::Interpreter &interp,
1035 const clang::FunctionDecl* funcD
1036 = interp.getLookupHelper().findFunctionProto(cinfo, method, proto,
1037 diagnose ? cling::LookupHelper::WithDiagnostics
1038 : cling::LookupHelper::NoDiagnostics);
1040 return llvm::dyn_cast<
const clang::CXXMethodDecl>(funcD);
1049 namespace TMetaUtils {
1052 const cling::LookupHelper& lh = interp.getLookupHelper();
1055 clang::QualType instanceType = lh.findType(type_of_arg, cling::LookupHelper::WithDiagnostics);
1056 if (!instanceType.isNull())
1057 fArgType = instanceType->getAsCXXRecordDecl();
1071 const cling::Interpreter &interp)
1073 if (cl->isAbstract())
return false;
1075 for (RConstructorTypes::const_iterator ctorTypeIt = ctorTypes.begin();
1076 ctorTypeIt!=ctorTypes.end(); ++ctorTypeIt) {
1083 std::string
proto( ctorTypeIt->GetName() );
1084 bool defaultCtor =
proto.empty();
1096 arg +=
")nullptr )";
1099 const clang::CXXMethodDecl *method
1101 cling::LookupHelper::NoDiagnostics);
1102 if (method && method->getAccess() != clang::AS_public) {
1117 if (!cl)
return false;
1119 if (cl->hasUserDeclaredDestructor()) {
1121 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1123 return (dest->getAccess() == clang::AS_public);
1135 const char *methodname,
1137 const cling::Interpreter &interp,
1140 const clang::CXXMethodDecl *method
1142 diagnose ? cling::LookupHelper::WithDiagnostics
1143 : cling::LookupHelper::NoDiagnostics);
1144 return (method && method->getAccess() == clang::AS_public);
1155 const char *
proto =
"TDirectory*";
1156 const char *name =
"DirectoryAutoAdd";
1170 const char *
proto =
"TCollection*,TFileMergeInfo*";
1171 const char *name =
"Merge";
1184 const char *
proto =
"TCollection*";
1185 const char *name =
"Merge";
1200 const char *
proto =
"TFileMergeInfo*";
1201 const char *name =
"ResetAfterMerge";
1211 const clang::CXXRecordDecl* clxx,
1212 const cling::Interpreter &interp,
1215 static const char *
proto =
"TBuffer&";
1217 const clang::CXXMethodDecl *method
1219 cling::LookupHelper::NoDiagnostics);
1220 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1222 return (method && method->getDeclContext() == clxx_as_context
1230 const clang::CXXRecordDecl* clxx,
1231 const cling::Interpreter &interp,
1234 static const char *
proto =
"TBuffer&,TClass*";
1236 const clang::CXXMethodDecl *method
1238 cling::LookupHelper::NoDiagnostics);
1239 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1241 return (method && method->getDeclContext() == clxx_as_context
1271 clang::QualType qualType(&type,0);
1303 llvm::raw_string_ostream stream(qual_name);
1304 clang::PrintingPolicy policy( cl.getASTContext().getPrintingPolicy() );
1305 policy.SuppressTagKeyword =
true;
1306 policy.SuppressUnwrittenScope =
true;
1308 cl.getNameForDiagnostic(stream,policy,
true);
1311 if ( qual_name ==
"(anonymous " ) {
1312 size_t pos = qual_name.find(
':');
1313 qual_name.erase(0,pos+2);
1329 const clang::Type* declType ( recordDecl.getTypeForDecl() );
1330 clang::QualType qualType(declType,0);
1364 std::stringstream dims;
1365 std::string typenameStr;
1367 const clang::ASTContext& astContext = cl.getASTContext();
1370 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
1378 typenameStr.clear();
1382 clang::QualType fieldType(field_iter->getType());
1383 if (fieldType->isConstantArrayType()) {
1384 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(fieldType.getTypePtr());
1386 dims <<
"[" << arrayType->getSize().getLimitedValue() <<
"]";
1387 fieldType = arrayType->getElementType();
1388 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1398 for(clang::CXXRecordDecl::base_class_const_iterator iter = cl.bases_begin(), end = cl.bases_end();
1401 std::string basename( iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1411 const cling::Interpreter &interp,
1414 return interp.getLookupHelper().findFunctionProto(cinfo, method, proto,
1415 diagnose ? cling::LookupHelper::WithDiagnostics
1416 : cling::LookupHelper::NoDiagnostics);
1450 clang::SourceLocation sourceLocation = decl->getLocation();
1451 clang::SourceManager& sourceManager = decl->getASTContext().getSourceManager();
1453 if (!sourceLocation.isValid() ) {
1457 if (!sourceLocation.isFileID()) {
1458 sourceLocation = sourceManager.getExpansionRange(sourceLocation).second;
1461 if (sourceLocation.isValid() && sourceLocation.isFileID()) {
1462 return sourceManager.getLineNumber(sourceManager.getFileID(sourceLocation),sourceManager.getFileOffset(sourceLocation));
1475 while (llvm::isa<clang::PointerType>(instanceType.getTypePtr())
1476 || llvm::isa<clang::ReferenceType>(instanceType.getTypePtr()))
1478 instanceType = instanceType->getPointeeType();
1481 const clang::ElaboratedType* etype
1482 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
1484 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1497 const clang::CXXRecordDecl* clxx = instanceType->getAsCXXRecordDecl();
1498 if (clxx && clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1500 const clang::TemplateSpecializationType* TST
1501 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instanceType.getTypePtr());
1508 for(clang::TemplateSpecializationType::iterator
1509 I = TST->begin(),
E = TST->end();
1527 const cling::Interpreter &interp,
1530 const clang::CXXRecordDecl* clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1531 if (clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
1533 clang::QualType instanceType = interp.getLookupHelper().findType(cl.
GetNormalizedName(),
1534 cling::LookupHelper::WithDiagnostics);
1535 if (instanceType.isNull()) {
1548 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(attribute);
1553 attrString = annAttr->getAnnotation();
1563 if (substrFound==std::string::npos) {
1568 attrName = attributeStr.substr(0, EndPart1);
1570 attrValue = attributeStr.substr(EndPart1 + separatorLength);
1578 std::string attrString;
1580 if (0!=ret)
return ret;
1588 const std::string& propName,
1589 std::string& propValue)
1591 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1592 attrIt!=decl.attr_end();++attrIt){
1593 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1594 if (!annAttr)
continue;
1596 llvm::StringRef attribute = annAttr->getAnnotation();
1597 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1598 if (split.first != propName.c_str())
continue;
1600 propValue = split.second;
1611 const std::string& propName,
1614 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1615 attrIt!=decl.attr_end();++attrIt){
1616 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1617 if (!annAttr)
continue;
1619 llvm::StringRef attribute = annAttr->getAnnotation();
1620 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1621 if (split.first != propName.c_str())
continue;
1623 return split.second.getAsInteger(10,propValue);
1634 const clang::CXXRecordDecl *decl,
1635 const cling::Interpreter &interp,
1638 bool& needCollectionProxy)
1642 std::string mappedname;
1644 std::string csymbol = classname;
1652 csymbol.insert(0,
"::");
1659 const cling::LookupHelper& lh = interp.getLookupHelper();
1662 bool isStdNotString = isStd && !isString;
1664 finalString <<
"namespace ROOT {" <<
"\n";
1668 finalString <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();\n" 1669 <<
" static void " << mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1675 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p = 0);" <<
"\n";
1679 finalString <<
" static void *newArray_";
1680 finalString << mappedname.c_str();
1681 finalString <<
"(Long_t size, void *p);";
1682 finalString <<
"\n";
1687 finalString <<
" static void delete_" << mappedname.c_str() <<
"(void *p);" <<
"\n" <<
" static void deleteArray_" << mappedname.c_str() <<
"(void *p);" <<
"\n" <<
" static void destruct_" << mappedname.c_str() <<
"(void *p);" <<
"\n";
1690 finalString <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1693 finalString <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1696 finalString <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1699 finalString <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1702 finalString <<
" static void reset_" << mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1709 std::string declName;
1711 ROOT::SchemaRuleClassMap_t::iterator rulesIt1 =
ROOT::gReadRules.find( declName.c_str() );
1712 ROOT::SchemaRuleClassMap_t::iterator rulesIt2 =
ROOT::gReadRawRules.find( declName.c_str() );
1723 finalString <<
"\n // Schema evolution read functions\n";
1724 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt1->second.begin();
1725 while( rIt != rulesIt1->second.end() ) {
1732 rIt = rulesIt1->second.erase(rIt);
1740 if( rIt->find(
"code" ) != rIt->end() ) {
1756 finalString <<
"\n // Schema evolution read raw functions\n";
1757 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt2->second.begin();
1758 while( rIt != rulesIt2->second.end() ) {
1765 rIt = rulesIt2->second.erase(rIt);
1773 if( rIt->find(
"code" ) == rIt->end() )
1781 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1783 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " << csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1785 finalString <<
" " << csymbol <<
" *ptr = 0;" <<
"\n";
1789 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " << csymbol <<
" >(0);" <<
"\n";
1792 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol <<
"));" <<
"\n";
1794 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1797 finalString << csymbol <<
"::Class_Version(), ";
1799 finalString <<
"2, ";
1801 finalString <<
"-2, ";
1807 static const char *versionFunc =
"GetClassVersion";
1811 std::string
proto = classname +
"*";
1812 const clang::Decl* ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1813 const clang::FunctionDecl *methodinfo
1815 interp, cling::LookupHelper::NoDiagnostics);
1823 finalString <<
"GetClassVersion< ";
1824 finalString << classname.c_str();
1825 finalString <<
" >(), ";
1833 if (filename.length() > 0) {
1834 for (
unsigned int i=0; i<filename.length(); i++) {
1835 if (filename[i]==
'\\') filename[i]=
'/';
1839 <<
"," <<
"\n" <<
" typeid(" << csymbol
1840 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1843 finalString <<
"&" << csymbol <<
"::Dictionary, ";
1845 finalString <<
"&" << mappedname <<
"_Dictionary, ";
1849 TClassTable__kHasCustomStreamerMember = 0x10
1854 rootflag = rootflag | TClassTable__kHasCustomStreamerMember;
1856 finalString <<
"isa_proxy, " << rootflag <<
"," <<
"\n" <<
" sizeof(" << csymbol <<
") );" <<
"\n";
1858 finalString <<
" instance.SetNew(&new_" << mappedname.c_str() <<
");" <<
"\n";
1860 finalString <<
" instance.SetNewArray(&newArray_" << mappedname.c_str() <<
");" <<
"\n";
1863 finalString <<
" instance.SetDelete(&delete_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" << mappedname.c_str() <<
");" <<
"\n";
1866 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" << mappedname.c_str() <<
");" <<
"\n";
1870 finalString <<
" instance.SetStreamerFunc(&streamer_" << mappedname.c_str() <<
");" <<
"\n";
1874 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" << mappedname.c_str() <<
");" <<
"\n";
1877 finalString <<
" instance.SetMerge(&merge_" << mappedname.c_str() <<
");" <<
"\n";
1880 finalString <<
" instance.SetResetAfterMerge(&reset_" << mappedname.c_str() <<
");" <<
"\n";
1883 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
1885 needCollectionProxy =
true;
1886 }
else if (stl != 0 &&
1889 int idx = classname.find(
"<");
1890 int stlType = (idx!=(int)std::string::npos) ?
TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
1891 const char* methodTCP=0;
1896 methodTCP=
"Pushback";
1899 methodTCP=
"Pushfront";
1905 methodTCP=
"MapInsert";
1917 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << methodTCP <<
"< " << classNameForIO.c_str() <<
" >()));" <<
"\n";
1919 needCollectionProxy =
true;
1927 finalString <<
"\n" <<
" ::ROOT::AddClassAlternate(\"" 1936 finalString <<
"\n" <<
" ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
1940 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<ROOT::Internal::TSchemaHelper> readrules(" << rulesIt1->second.size() <<
");" <<
"\n";
1942 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
1946 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<ROOT::Internal::TSchemaHelper> readrawrules(" << rulesIt2->second.size() <<
");" <<
"\n";
1948 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
1951 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
1955 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " << csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal((" << csymbol <<
"*)0);\n }" <<
"\n";
1958 finalString <<
" // Static variable to force the class initialization" <<
"\n";
1962 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstanceLocal((const " << csymbol <<
"*)0x0); R__UseDummy(_R__UNIQUE_(Init));" <<
"\n";
1965 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n" 1966 <<
" static TClass *" << mappedname <<
"_Dictionary() {\n" 1967 <<
" TClass* theClass =" 1968 <<
"::ROOT::GenerateInitInstanceLocal((const " << csymbol <<
"*)0x0)->GetClass();\n" 1969 <<
" " << mappedname <<
"_TClassManip(theClass);\n";
1970 finalString <<
" return theClass;\n";
1971 finalString <<
" }\n\n";
1975 std::string manipString;
1976 std::string attribute_s;
1977 std::string attrName, attrValue;
1979 bool attrMapExtracted =
false;
1980 if (decl->hasAttrs()){
1982 for (clang::Decl::attr_iterator attrIt = decl->attr_begin();
1983 attrIt!=decl->attr_end();++attrIt){
1990 if (attrName ==
"name" ||
1991 attrName ==
"pattern" ||
1992 attrName ==
"rootmap")
continue;
1998 if (!attrMapExtracted){
1999 manipString+=
" theClass->CreateAttributeMap();\n";
2000 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2001 attrMapExtracted=
true;
2003 manipString+=
" attrMap->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2009 for(clang::CXXRecordDecl::decl_iterator internalDeclIt = decl->decls_begin();
2010 internalDeclIt != decl->decls_end(); ++internalDeclIt){
2011 if (!(!(*internalDeclIt)->isImplicit()
2012 && (clang::isa<clang::FieldDecl>(*internalDeclIt) ||
2013 clang::isa<clang::VarDecl>(*internalDeclIt))))
continue;
2016 if (!internalDeclIt->hasAttrs())
continue;
2018 attrMapExtracted =
false;
2019 bool memberPtrCreated =
false;
2021 for (clang::Decl::attr_iterator attrIt = internalDeclIt->attr_begin();
2022 attrIt!=internalDeclIt->attr_end();++attrIt){
2030 clang::NamedDecl* namedInternalDecl = clang::dyn_cast<clang::NamedDecl> (*internalDeclIt);
2031 if (!namedInternalDecl) {
2035 const std::string memberName(namedInternalDecl->getName());
2036 const std::string cppMemberName=
"theMember_"+memberName;
2039 const std::string dataMemberCreation=
" TDataMember* "+cppMemberName+
" = theClass->GetDataMember(\""+memberName+
"\");\n";
2052 if (!memberPtrCreated){
2053 manipString+=dataMemberCreation;
2054 memberPtrCreated=
true;
2057 if (!attrMapExtracted){
2058 manipString+=
" "+cppMemberName+
"->CreateAttributeMap();\n";
2059 manipString+=
" TDictAttributeMap* memberAttrMap_"+memberName+
"( theMember_"+memberName+
"->GetAttributeMap() );\n";
2060 attrMapExtracted=
true;
2063 manipString+=
" memberAttrMap_"+memberName+
"->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2070 finalString <<
" static void " << mappedname <<
"_TClassManip(TClass* " << (manipString.empty() ?
"":
"theClass") <<
"){\n" 2075 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2085 std::string &clsname,
2086 std::string &nsname,
2087 const clang::CXXRecordDecl *cl)
2097 auto ctxt = cl->getEnclosingNamespaceContext();
2098 while(ctxt && ctxt!=cl && ctxt->isInlineNamespace()) {
2099 ctxt = ctxt->getParent();
2102 const clang::NamedDecl *namedCtxt = llvm::dyn_cast<clang::NamedDecl>(ctxt);
2103 if (namedCtxt && namedCtxt!=cl) {
2104 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(namedCtxt);
2105 if (nsdecl != 0 && !nsdecl->isAnonymousNamespace()) {
2107 clsname.erase (0, nsname.size() + 2);
2119 const clang::DeclContext *ctxt = cl.getDeclContext();
2120 while(ctxt && !ctxt->isNamespace()) {
2121 ctxt = ctxt->getParent();
2135 int closing_brackets = 0;
2139 if (ctxt && ctxt->isNamespace()) {
2144 const clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(ctxt);
2147 out <<
"namespace " << ns->getNameAsString() <<
" {" << std::endl;
2151 return closing_brackets;
2165 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2166 if (kind == clang::TSK_Undeclared ) {
2169 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2183 const char *name = which;
2184 const char *
proto =
"size_t";
2185 const char *protoPlacement =
"size_t,void*";
2188 const clang::FunctionDecl *operatornew
2190 name, proto, interp,
2191 cling::LookupHelper::NoDiagnostics);
2192 const clang::FunctionDecl *operatornewPlacement
2194 name, protoPlacement, interp,
2195 cling::LookupHelper::NoDiagnostics);
2197 const clang::DeclContext *ctxtnew = 0;
2198 const clang::DeclContext *ctxtnewPlacement = 0;
2201 ctxtnew = operatornew->getParent();
2203 if (operatornewPlacement) {
2204 ctxtnewPlacement = operatornewPlacement->getParent();
2210 operatornewPlacement
2215 ctxtnew = operatornew->getParent();
2217 if (operatornewPlacement) {
2218 ctxtnewPlacement = operatornewPlacement->getParent();
2221 if (ctxtnewPlacement == 0) {
2229 if (ctxtnew == ctxtnewPlacement) {
2233 const clang::CXXRecordDecl* clnew = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnew);
2234 const clang::CXXRecordDecl* clnewPlacement = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnewPlacement);
2235 if (clnew == 0 && clnewPlacement == 0) {
2241 if (clnew != 0 && clnewPlacement == 0) {
2245 if (clnew == 0 && clnewPlacement != 0) {
2250 if (clnew->isDerivedFrom(clnewPlacement)) {
2280 const clang::CXXRecordDecl *decl,
2281 const cling::Interpreter &interp,
2287 std::string mappedname;
2305 classname.insert(0,
"::");
2308 finalString <<
"namespace ROOT {" <<
"\n";
2313 finalString <<
" // Wrappers around operator new" <<
"\n";
2314 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2316 finalString <<
"new(p) ";
2317 finalString << classname.c_str();
2318 finalString << args;
2319 finalString <<
" : ";
2321 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2322 finalString << classname.c_str();
2323 finalString << args;
2324 finalString <<
" : ";
2326 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2327 finalString <<
" }" <<
"\n";
2331 finalString <<
" static void *newArray_";
2332 finalString << mappedname.c_str();
2333 finalString <<
"(Long_t nElements, void *p) {";
2334 finalString <<
"\n";
2335 finalString <<
" return p ? ";
2337 finalString <<
"new(p) ";
2338 finalString << classname.c_str();
2339 finalString <<
"[nElements] : ";
2341 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2342 finalString << classname.c_str();
2343 finalString <<
"[nElements] : ";
2345 finalString <<
"new ";
2346 finalString << classname.c_str();
2347 finalString <<
"[nElements];";
2348 finalString <<
"\n";
2349 finalString <<
" }";
2350 finalString <<
"\n";
2355 finalString <<
" // Wrapper around operator delete" <<
"\n" <<
" static void delete_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" delete ((" << classname.c_str() <<
"*)p);" <<
"\n" <<
" }" <<
"\n" <<
" static void deleteArray_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" delete [] ((" << classname.c_str() <<
"*)p);" <<
"\n" <<
" }" <<
"\n" <<
" static void destruct_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" typedef " << classname.c_str() <<
" current_t;" <<
"\n" <<
" ((current_t*)p)->~current_t();" <<
"\n" <<
" }" <<
"\n";
2359 finalString <<
" // Wrapper around the directory auto add." <<
"\n" <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *p, TDirectory *dir) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)p)->DirectoryAutoAdd(dir);" <<
"\n" <<
" }" <<
"\n";
2363 finalString <<
" // Wrapper around a custom streamer member function." <<
"\n" <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->" << classname.c_str() <<
"::Streamer(buf);" <<
"\n" <<
" }" <<
"\n";
2367 finalString <<
" // Wrapper around a custom streamer member function." <<
"\n" <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass *onfile_class) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->" << classname.c_str() <<
"::Streamer(buf,onfile_class);" <<
"\n" <<
" }" <<
"\n";
2371 finalString <<
" // Wrapper around the merge function." <<
"\n" <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj,TCollection *coll,TFileMergeInfo *info) {" <<
"\n" <<
" return ((" << classname.c_str() <<
"*)obj)->Merge(coll,info);" <<
"\n" <<
" }" <<
"\n";
2373 finalString <<
" // Wrapper around the merge function." <<
"\n" <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj,TCollection *coll,TFileMergeInfo *) {" <<
"\n" <<
" return ((" << classname.c_str() <<
"*)obj)->Merge(coll);" <<
"\n" <<
" }" <<
"\n";
2377 finalString <<
" // Wrapper around the Reset function." <<
"\n" <<
" static void reset_" << mappedname.c_str() <<
"(void *obj,TFileMergeInfo *info) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->ResetAfterMerge(info);" <<
"\n" <<
" }" <<
"\n";
2379 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2386 const cling::Interpreter &interp,
2393 if (version == 0)
return;
2397 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2398 if (clxx == 0)
return;
2401 for(clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
2412 for(clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
2416 std::string mTypename;
2422 if (!strcmp(shortTypeName,
"string")) {
2444 const clang::Type *rawtype = m.getType()->getCanonicalTypeInternal().getTypePtr();
2445 if (rawtype->isArrayType()) {
2446 rawtype = rawtype->getBaseElementTypeUnsafe ();
2460 const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2468 if (!funcCV)
return -1;
2470 if (funcCV == (clang::FunctionDecl*)-1)
return 1;
2472 const clang::CompoundStmt* FuncBody
2473 = llvm::dyn_cast_or_null<clang::CompoundStmt>(funcCV->getBody());
2474 if (!FuncBody)
return -1;
2475 if (FuncBody->size() != 1) {
2481 const clang::ReturnStmt* RetStmt
2482 = llvm::dyn_cast<clang::ReturnStmt>(FuncBody->body_back());
2483 if (!RetStmt)
return -1;
2484 const clang::Expr* RetExpr = RetStmt->getRetValue();
2490 llvm::APSInt RetRes;
2491 if (!RetExpr->isIntegerConstantExpr(RetRes, funcCV->getASTContext()))
2493 if (RetRes.isSigned()) {
2494 return (
Version_t)RetRes.getSExtValue();
2497 return (
Version_t)RetRes.getZExtValue();
2513 clang::QualType type = m.getType();
2525 clang::QualType type = base.getType();
2540 static char t[4096];
2541 static const char* constwd =
"const ";
2542 static const char* constwdend =
"const";
2547 for (s=typeDesc;*s;s++) {
2550 if (lev==0 && *s==
'*')
continue;
2551 if (lev==0 && (strncmp(constwd,s,strlen(constwd))==0
2552 ||strcmp(constwdend,s)==0 ) ) {
2553 s+=strlen(constwd)-1;
2556 if (lev==0 && *s==
' ' && *(s+1)!=
'*') { p = t;
continue;}
2557 if (p - t > (
long)
sizeof(t)) {
2558 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2571 const cling::Interpreter& interp)
2576 if (comment[0] ==
'!')
return false;
2578 clang::QualType type = m.getType();
2580 if (type->isReferenceType()) {
2585 std::string mTypeName = type.getAsString(m.getASTContext().getPrintingPolicy());
2586 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2589 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2597 const clang::Type *rawtype = type.getTypePtr()->getBaseElementTypeUnsafe ();
2599 if (rawtype->isPointerType()) {
2601 clang::QualType pointee;
2602 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2604 rawtype = pointee.getTypePtr();
2608 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2613 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2617 if (version > 0)
return true;
2630 const clang::Type *rawtype = m.getType().getTypePtr();
2633 clang::QualType pointee;
2634 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2636 rawtype = pointee.getTypePtr();
2650 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2654 return rawtype->getAsCXXRecordDecl();
2663 const cling::Interpreter &interp,
2665 std::ostream& dictStream,
2667 bool isGenreflex=
false)
2669 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2671 if (!decl || !decl->isCompleteDefinition()) {
2675 std::string fullname;
2687 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2689 ROOT::TMetaUtils::Info(0,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2711 const cling::Interpreter &interpreter,
2714 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2716 clang::QualType originalType = instanceType;
2720 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2722 clang::Qualifiers quals = instanceType.getQualifiers();
2723 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2724 if (newPointee != instanceType->getPointeeType()) {
2725 instanceType = Ctx.getPointerType(newPointee);
2727 instanceType = Ctx.getQualifiedType(instanceType, quals);
2729 return instanceType;
2734 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2736 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2737 clang::Qualifiers quals = instanceType.getQualifiers();
2738 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2740 if (newPointee != instanceType->getPointeeType()) {
2743 instanceType = Ctx.getLValueReferenceType(newPointee);
2745 instanceType = Ctx.getRValueReferenceType(newPointee);
2747 instanceType = Ctx.getQualifiedType(instanceType, quals);
2749 return instanceType;
2753 bool prefix_changed =
false;
2754 clang::NestedNameSpecifier* prefix = 0;
2755 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2756 const clang::ElaboratedType* etype
2757 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2760 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2761 prefix_changed = prefix != etype->getQualifier();
2762 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2768 const clang::TemplateSpecializationType* TST
2769 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2771 const clang::ClassTemplateSpecializationDecl* TSTdecl
2772 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2784 bool mightHaveChanged =
false;
2785 if (TST && TSTdecl) {
2787 clang::Sema&
S = interpreter.getCI()->getSema();
2788 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2789 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2790 clang::TemplateParameterList::iterator Param = Params->begin();
2794 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2796 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2797 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2798 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2799 for(clang::TemplateSpecializationType::iterator
2800 I = TST->begin(),
E = TST->end();
2802 I!=
E ? ++
I : 0, ++Idecl, ++Param) {
2806 if (
I->getKind() == clang::TemplateArgument::Template) {
2807 clang::TemplateName templateName =
I->getAsTemplate();
2808 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2810 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2812 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2813 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2814 clang::NestedNameSpecifier* nns;
2816 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx, ns);
2817 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2818 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2821 desArgs.push_back(*
I);
2824 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, templateDecl) );
2825 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2826 mightHaveChanged =
true;
2833 desArgs.push_back(*
I);
2837 clang::QualType SubTy =
I->getAsType();
2846 if (SubTy != newSubTy) {
2847 mightHaveChanged =
true;
2848 desArgs.push_back(clang::TemplateArgument(newSubTy));
2850 desArgs.push_back(*
I);
2853 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
2855 mightHaveChanged =
true;
2857 const clang::TemplateArgument& templateArg
2858 = TSTdecl->getTemplateArgs().get(Idecl);
2860 desArgs.push_back(templateArg);
2863 clang::QualType SubTy = templateArg.getAsType();
2865 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
2866 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
2868 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
2871 cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
2872 clang::sema::HackForDefaultTemplateArg raii;
2873 bool HasDefaultArgs;
2874 clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
2883 if (ArgType.getArgument().isNull()
2886 "Template parameter substitution failed for %s around %s",
2887 instanceType.getAsString().c_str(),
2888 SubTy.getAsString().c_str()
2892 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
2893 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
2896 desArgs.push_back(clang::TemplateArgument(SubTy));
2905 if (mightHaveChanged) {
2906 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
2909 TST->getCanonicalTypeInternal());
2913 if (!prefix_changed && !mightHaveChanged)
return originalType;
2915 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
2916 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
2918 return instanceType;
2938 llvm::StringRef title;
2941 if (clang::AnnotateAttr *
A = m.getAttr<clang::AnnotateAttr>())
2942 title =
A->getAnnotation();
2954 if (errnum) *errnum =
VALID;
2956 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
2957 size_t rightbracket = title.find(
']');
2958 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
2960 std::string working;
2961 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
2968 size_t indexvarlen = indexvar.size();
2969 for ( i=0; i<indexvarlen; i++) {
2970 if (!isspace(indexvar[i])) {
2971 working += indexvar[i];
2976 const char *tokenlist =
"*+-";
2977 char *current =
const_cast<char*
>(working.c_str());
2978 current = strtok(current,tokenlist);
2980 while (current!=0) {
2982 if (isdigit(current[0])) {
2983 for(i=0;i<strlen(current);i++) {
2984 if (!isdigit(current[0])) {
2989 if (errstr) *errstr = current;
2990 if (errnum) *errnum =
NOT_INT;
2991 return llvm::StringRef();
2997 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(m.getDeclContext());
2998 const clang::FieldDecl *index1 = 0;
3000 index1 = GetDataMemberFromAll(*parent_clxx, current );
3002 if ( IsFieldDeclInt(index1) ) {
3008 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3012 if ( field_iter->getNameAsString() == m.getNameAsString() ) {
3018 if (errstr) *errstr = current;
3019 if (errnum) *errnum =
NOT_DEF;
3020 return llvm::StringRef();
3022 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3030 if (errstr) *errstr = current;
3031 if (errnum) *errnum =
NOT_INT;
3032 return llvm::StringRef();
3037 index1 = GetDataMemberFromAllParents( *parent_clxx, current );
3039 if ( IsFieldDeclInt(index1) ) {
3046 if (errnum) *errnum =
NOT_INT;
3047 if (errstr) *errstr = current;
3051 if (errnum) *errnum =
NOT_INT;
3052 if (errstr) *errstr = current;
3053 return llvm::StringRef();
3055 if ( found && (index1->getAccess() == clang::AS_private) ) {
3058 if (errstr) *errstr = current;
3060 return llvm::StringRef();
3067 if (errstr) *errstr = indexvar;
3068 if (errnum) *errnum =
UNKNOWN;
3069 return llvm::StringRef();
3074 current = strtok(0,tokenlist);
3087 out.resize(strlen(in)*2);
3088 unsigned int i=0,j=0,
c;
3090 if (out.capacity() < (j+3)) {
3094 case '+': strcpy(const_cast<char*>(out.data())+j,
"pL"); j+=2;
break;
3095 case '-': strcpy(const_cast<char*>(out.data())+j,
"mI"); j+=2;
break;
3096 case '*': strcpy(const_cast<char*>(out.data())+j,
"mU"); j+=2;
break;
3097 case '/': strcpy(const_cast<char*>(out.data())+j,
"dI"); j+=2;
break;
3098 case '&': strcpy(const_cast<char*>(out.data())+j,
"aN"); j+=2;
break;
3099 case '%': strcpy(const_cast<char*>(out.data())+j,
"pE"); j+=2;
break;
3100 case '|': strcpy(const_cast<char*>(out.data())+j,
"oR"); j+=2;
break;
3101 case '^': strcpy(const_cast<char*>(out.data())+j,
"hA"); j+=2;
break;
3102 case '>': strcpy(const_cast<char*>(out.data())+j,
"gR"); j+=2;
break;
3103 case '<': strcpy(const_cast<char*>(out.data())+j,
"lE"); j+=2;
break;
3104 case '=': strcpy(const_cast<char*>(out.data())+j,
"eQ"); j+=2;
break;
3105 case '~': strcpy(const_cast<char*>(out.data())+j,
"wA"); j+=2;
break;
3106 case '.': strcpy(const_cast<char*>(out.data())+j,
"dO"); j+=2;
break;
3107 case '(': strcpy(const_cast<char*>(out.data())+j,
"oP"); j+=2;
break;
3108 case ')': strcpy(const_cast<char*>(out.data())+j,
"cP"); j+=2;
break;
3109 case '[': strcpy(const_cast<char*>(out.data())+j,
"oB"); j+=2;
break;
3110 case ']': strcpy(const_cast<char*>(out.data())+j,
"cB"); j+=2;
break;
3111 case '!': strcpy(const_cast<char*>(out.data())+j,
"nO"); j+=2;
break;
3112 case ',': strcpy(const_cast<char*>(out.data())+j,
"cO"); j+=2;
break;
3113 case '$': strcpy(const_cast<char*>(out.data())+j,
"dA"); j+=2;
break;
3114 case ' ': strcpy(const_cast<char*>(out.data())+j,
"sP"); j+=2;
break;
3115 case ':': strcpy(const_cast<char*>(out.data())+j,
"cL"); j+=2;
break;
3116 case '"': strcpy(const_cast<char*>(out.data())+j,
"dQ"); j+=2;
break;
3117 case '@': strcpy(const_cast<char*>(out.data())+j,
"aT"); j+=2;
break;
3118 case '\'': strcpy(const_cast<char*>(out.data())+j,
"sQ"); j+=2;
break;
3119 case '\\': strcpy(const_cast<char*>(out.data())+j,
"fI"); j+=2;
break;
3120 default: out[j++]=
c;
break;
3127 std::size_t firstNonNumber = out.find_first_not_of(
"0123456789");
3128 out.replace(0,firstNonNumber,
"");
3133 static clang::SourceLocation
3135 clang::SourceLocation sourceLoc) {
3137 if (!sourceLoc.isFileID()) {
3138 return sourceManager.getExpansionRange(sourceLoc).second;
3147 const cling::Interpreter& interp)
3177 using namespace clang;
3178 SourceLocation headerLoc = decl.getLocation();
3180 static const char invalidFilename[] =
"";
3181 if (!headerLoc.isValid())
return invalidFilename;
3183 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3185 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3187 FileID headerFID = sourceManager.getFileID(headerLoc);
3188 SourceLocation includeLoc
3190 sourceManager.getIncludeLoc(headerFID));
3192 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3193 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3194 const DirectoryLookup *foundDir = 0;
3197 const FileEntry *FEhdr
3198 = HdrSearch.LookupFile(llvm::sys::path::filename(headerFE->getName()),
3201 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3208 headerFID = sourceManager.getFileID(includeLoc);
3209 headerFE = sourceManager.getFileEntryForID(headerFID);
3211 sourceManager.getIncludeLoc(headerFID));
3214 if (!headerFE)
return invalidFilename;
3215 llvm::StringRef headerFileName = headerFE->getName();
3226 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3227 const FileEntry* FELong = 0;
3229 for (llvm::sys::path::const_iterator
3230 IDir = llvm::sys::path::begin(headerFileName),
3231 EDir = llvm::sys::path::end(headerFileName);
3232 !FELong && IDir != EDir; ++IDir) {
3238 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3239 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3240 assert(trailingPart.data() + trailingPart.size()
3241 == headerFileName.data() + headerFileName.size()
3242 &&
"Mismatched partitioning of file name!");
3243 const DirectoryLookup* FoundDir = 0;
3244 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3246 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3253 return invalidFilename;
3257 for (llvm::sys::path::reverse_iterator
3258 IDir = llvm::sys::path::rbegin(headerFileName),
3259 EDir = llvm::sys::path::rend(headerFileName);
3260 IDir != EDir; ++IDir) {
3261 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3262 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3263 assert(trailingPart.data() + trailingPart.size()
3264 == headerFileName.data() + headerFileName.size()
3265 &&
"Mismatched partitioning of file name!");
3266 const DirectoryLookup* FoundDir = 0;
3269 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3271 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3275 return trailingPart;
3279 return invalidFilename;
3285 const clang::QualType &qtype,
3286 const clang::ASTContext &astContext)
3288 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3297 const clang::QualType &qtype,
3298 const cling::Interpreter &interpreter)
3302 interpreter.getCI()->getASTContext());
3314 const char* rootsys = getenv(
"ROOTSYS");
3316 Error(0,
"Environment variable ROOTSYS not set!");
3319 return std::string(
"-I") + rootsys +
"/etc";
3322 return std::string(
"-I") + ROOTETCDIR;
3331 #ifdef R__EXTERN_LLVMDIR 3332 return R__EXTERN_LLVMDIR;
3335 .substr(2, std::string::npos) +
"/cling";
3344 clang::ClassTemplateDecl*& ctd,
3345 clang::ClassTemplateSpecializationDecl*& ctsd)
3347 using namespace clang;
3348 const Type* theType = qt.getTypePtr();
3355 if (theType->isPointerType()) {
3359 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3360 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3362 ctd = ctsd->getSpecializedTemplate();
3367 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3372 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3374 ctd = ctsd->getSpecializedTemplate();
3389 using namespace clang;
3390 ClassTemplateSpecializationDecl* ctsd;
3391 ClassTemplateDecl* ctd;
3405 using namespace clang;
3406 TemplateName theTemplateName;
3408 const Type* theType = qt.getTypePtr();
3410 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3411 theTemplateName = tst->getTemplateName();
3414 theTemplateName = TemplateName(ctd);
3417 return theTemplateName;
3423 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3424 const clang::NamedDecl& tPar,
3425 const cling::Interpreter& interp,
3429 using namespace clang;
3432 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3433 if (!ttpdPtr)
return false;
3434 if (!ttpdPtr->hasDefaultArgument())
return false;
3437 QualType tParQualType = ttpdPtr->getDefaultArgument();
3438 const QualType tArgQualType = tArg.getAsType();
3445 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3456 const clang::ElaboratedType* etype
3457 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3459 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3460 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3463 const TemplateSpecializationType* tst =
3464 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3469 ClassTemplateSpecializationDecl* TSTdecl
3470 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3475 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3478 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3481 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3486 TemplateArgument newArg = tArg;
3488 clang::Sema&
S = interp.getCI()->getSema();
3489 cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
3490 clang::sema::HackForDefaultTemplateArg raii;
3491 bool HasDefaultArgs;
3492 TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
3500 newArg = defTArgLoc.getArgument();
3501 if (newArg.isNull() ||
3504 "Template parameter substitution failed!");
3507 ClassTemplateSpecializationDecl* nTSTdecl
3508 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3511 isEqual = nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl() ||
3512 tParQualType.getTypePtr() == newArg.getAsType().getTypePtr();
3524 const clang::NamedDecl& tPar)
3526 using namespace clang;
3527 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3528 if (!nttpdPtr)
return false;
3529 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3531 if (!nttpd.hasDefaultArgument())
3535 llvm::APSInt defaultValueAPSInt(64,
false);
3536 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3537 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3538 defArgExpr->isIntegerConstantExpr(defaultValueAPSInt, astCtxt);
3541 const int value = tArg.getAsIntegral().getLimitedValue();
3544 return value == defaultValueAPSInt;
3554 using namespace clang;
3555 if (!nDecl)
return false;
3556 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3557 return ttpd->hasDefaultArgument();
3558 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3559 return nttpd->hasDefaultArgument();
3564 static void KeepNParams(clang::QualType& normalizedType,
3565 const clang::QualType& vanillaType,
3566 const cling::Interpreter& interp,
3571 const clang::TemplateArgument &tArg,
3572 const cling::Interpreter& interp,
3574 const clang::ASTContext& astCtxt)
3577 using namespace clang;
3585 QualType thisNormQualType = normTArg.getAsType();
3586 QualType thisArgQualType = tArg.getAsType();
3591 normTArg = TemplateArgument(thisNormQualType);
3592 return (thisNormQualType != thisArgQualType);
3593 }
else if (normTArg.getKind() == clang::TemplateArgument::Pack) {
3594 assert( tArg.getKind() == clang::TemplateArgument::Pack );
3596 SmallVector<TemplateArgument, 2> desArgs;
3597 bool mightHaveChanged =
true;
3598 for (
auto I = normTArg.pack_begin(),
E = normTArg.pack_end(),
3599 FI = tArg.pack_begin(), FE = tArg.pack_end();
3600 I !=
E && FI != FE; ++
I, ++FI)
3602 TemplateArgument pack_arg(*
I);
3604 desArgs.push_back(pack_arg);
3606 if (mightHaveChanged) {
3607 ASTContext &mutableCtx( const_cast<ASTContext&>(astCtxt) );
3608 normTArg = TemplateArgument::CreatePackCopy(mutableCtx, desArgs);
3610 return mightHaveChanged;
3621 const clang::QualType& vanillaType,
3622 const cling::Interpreter& interp,
3626 using namespace clang;
3630 ClassTemplateSpecializationDecl* ctsd;
3631 ClassTemplateDecl* ctd;
3638 QualType originalNormalizedType = normalizedType;
3640 const ASTContext& astCtxt = ctsd->getASTContext();
3645 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3647 clang::Qualifiers quals = normalizedType.getQualifiers();
3648 auto valNormalizedType = normalizedType->getPointeeType();
3649 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3650 normalizedType = astCtxt.getPointerType(valNormalizedType);
3652 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3658 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3660 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3661 clang::Qualifiers quals = normalizedType.getQualifiers();
3662 auto valNormType = normalizedType->getPointeeType();
3663 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3667 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3669 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3671 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3676 bool prefix_changed =
false;
3677 clang::NestedNameSpecifier* prefix =
nullptr;
3678 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3679 const clang::ElaboratedType* etype
3680 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3684 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3685 prefix_changed = prefix != etype->getQualifier();
3686 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3692 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3693 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3694 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3695 if (tpl->getMinRequiredArguments () < tpl->size())
3696 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3698 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3699 const TemplateParameterList& tPars = *tParsPtr;
3700 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3704 if (theTemplateName.isNull()) {
3705 normalizedType=originalNormalizedType;
3709 const TemplateSpecializationType* normalizedTst =
3710 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3711 if (!normalizedTst) {
3712 normalizedType=originalNormalizedType;
3716 const clang::ClassTemplateSpecializationDecl* TSTdecl
3717 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3725 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3727 const int nArgs = tArgs.size();
3728 const int nNormArgs = normalizedTst->getNumArgs();
3730 bool mightHaveChanged =
false;
3733 for (
int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
3734 const NamedDecl* tParPtr = tPars.getParam(formal);
3736 Error(
"KeepNParams",
"The parameter number %s is null.\n", formal);
3743 if (formal == nNormArgs || inst == nNormArgs)
break;
3745 const TemplateArgument& tArg = tArgs.get(formal);
3746 TemplateArgument normTArg(normalizedTst->getArgs()[inst]);
3748 bool shouldKeepArg = nArgsToKeep < 0 || inst <
nArgsToKeep;
3749 if (isStdDropDefault) shouldKeepArg =
false;
3758 if ( tParPtr->isTemplateParameterPack() ) {
3763 for( ; inst != nNormArgs; ++inst) {
3764 normTArg = normalizedTst->getArgs()[inst];
3766 argsToKeep.push_back(normTArg);
3772 argsToKeep.push_back(normTArg);
3775 if (!isStdDropDefault) {
3777 mightHaveChanged =
true;
3787 auto argKind = tArg.getKind();
3790 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3791 }
else if (argKind == clang::TemplateArgument::Integral){
3796 argsToKeep.push_back(normTArg);
3798 mightHaveChanged =
true;
3804 if (!prefix_changed && !mightHaveChanged) {
3805 normalizedType = originalNormalizedType;
3810 if (mightHaveChanged) {
3811 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3812 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3815 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3816 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3822 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3823 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3837 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3839 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt, type, normCtxt.
GetConfig(),
true );
3845 KeepNParams(normalizedType,type,interpreter,normCtxt);
3847 return normalizedType;
3861 if (type.isNull()) {
3868 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3869 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
3870 policy.SuppressTagKeyword =
true;
3871 policy.SuppressScope =
true;
3872 policy.AnonymousTagLocations =
false;
3877 std::string normalizedNameStep1;
3878 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
3888 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
3889 norm_name.erase(0,2);
3897 const clang::TypeDecl* typeDecl,
3898 const cling::Interpreter &interpreter)
3901 const clang::Sema &sema = interpreter.getSema();
3902 clang::ASTContext& astCtxt = sema.getASTContext();
3903 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
3912 std::pair<std::string,clang::QualType>
3914 const cling::Interpreter &interpreter,
3918 std::string thisTypeName;
3922 if (!hasChanged)
return std::make_pair(thisTypeName,thisType);
3926 "Name changed from %s to %s\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
3929 auto& lookupHelper = interpreter.getLookupHelper();
3932 lookupHelper.findScope(thisTypeNameForIO,
3933 cling::LookupHelper::DiagSetting::NoDiagnostics,
3937 if (!typePtrForIO) {
3939 "Type not found: %s.",thisTypeNameForIO.c_str());
3942 clang::QualType typeForIO(typePtrForIO,0);
3945 if (!typeForIO->isRecordType()) {
3946 return std::make_pair(thisTypeNameForIO,typeForIO);
3949 auto thisDeclForIO = typeForIO->getAsCXXRecordDecl();
3950 if (!thisDeclForIO) {
3952 "The type for IO corresponding to %s is %s and it could not be found in the AST as class.\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
3953 return std::make_pair(thisTypeName,thisType);
3956 return std::make_pair(thisTypeNameForIO,typeForIO);
3962 const cling::Interpreter &interpreter,
3973 const std::string defaultInclude (
"include");
3976 const char* rootSysContent = getenv(
"ROOTSYS");
3977 if (rootSysContent) {
3978 std::string incl_rootsys (rootSysContent);
3979 return incl_rootsys +
"/" + defaultInclude;
3981 Error(0,
"Environment variable ROOTSYS not set");
3982 return defaultInclude;
3989 return defaultInclude;
3997 std::string dictFileName(moduleName);
3998 dictFileName +=
"_rdict.pcm";
3999 return dictFileName;
4006 const char* moduleFileName,
4007 const char* headers[])
4009 clang::Preprocessor& PP = CI->getPreprocessor();
4010 clang::ModuleMap& ModuleMap = PP.getHeaderSearchInfo().getModuleMap();
4013 clang::HeaderSearch& HS = CI->getPreprocessor().getHeaderSearchInfo();
4014 HS.setModuleCachePath(llvm::sys::path::parent_path(moduleFileName));
4016 llvm::StringRef moduleName = llvm::sys::path::filename(moduleFileName);
4017 moduleName = llvm::sys::path::stem(moduleName);
4019 std::pair<clang::Module*, bool> modCreation;
4022 = ModuleMap.findOrCreateModule(moduleName.str(),
4025 if (!modCreation.second && !strstr(moduleFileName,
"/allDict_rdict.pcm")) {
4026 std::cerr <<
"TMetaUtils::declareModuleMap: " 4027 "Duplicate definition of dictionary module " 4028 << moduleFileName << std::endl;
4033 clang::HeaderSearch& HdrSearch = PP.getHeaderSearchInfo();
4034 for (
const char** hdr = headers; hdr && *hdr; ++hdr) {
4035 const clang::DirectoryLookup* CurDir;
4036 const clang::FileEntry* hdrFileEntry
4037 = HdrSearch.LookupFile(*hdr, clang::SourceLocation(),
4039 llvm::ArrayRef<std::pair<
const clang::FileEntry *,
4040 const clang::DirectoryEntry *>>(),
4045 if (!hdrFileEntry) {
4046 std::cerr <<
"TMetaUtils::declareModuleMap: " 4047 "Cannot find header file " << *hdr
4048 <<
" included in dictionary module " 4050 <<
" in include search path!";
4051 hdrFileEntry = PP.getFileManager().getFile(*hdr,
false,
4053 }
else if (getenv(
"ROOT_MODULES")) {
4055 llvm::StringRef srHdrDir(hdrFileEntry->getName());
4056 srHdrDir = llvm::sys::path::parent_path(srHdrDir);
4057 const clang::DirectoryEntry* Dir
4058 = PP.getFileManager().getDirectory(srHdrDir);
4060 HdrSearch.setDirectoryHasModuleMap(Dir);
4064 ModuleMap.addHeader(modCreation.first,
4065 clang::Module::Header{*hdr,hdrFileEntry},
4066 clang::ModuleMap::NormalHeader);
4068 return modCreation.first;
4072 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4098 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4099 clang::SourceLocation sourceLocation = decl.getLocEnd();
4102 sourceLocation = sourceManager.getExpansionRange(sourceLocation).second;
4103 if (sourceManager.isLoadedSourceLocation(sourceLocation)) {
4109 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4113 bool skipToSemi =
true;
4114 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4115 if (FD->isImplicit()) {
4119 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4123 }
else if (FD->doesThisDeclarationHaveABody()) {
4126 assert((decl.getLocEnd() != sourceLocation || *commentStart ==
'}' 4128 &&
"Expected macro or end of body at '}'");
4129 if (*commentStart) ++commentStart;
4132 while (*commentStart && isspace(*commentStart)
4133 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4136 if (*commentStart ==
';') ++commentStart;
4140 }
else if (
const clang::EnumConstantDecl* ECD
4141 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4143 if (ECD->getNextDeclInContext())
4144 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4152 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4154 if (*commentStart ==
';') ++commentStart;
4158 while ( *commentStart && isspace(*commentStart)
4159 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4163 if (commentStart[0] !=
'/' ||
4164 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4174 unsigned int skipChars = 2;
4175 if (commentStart[0] ==
'/' &&
4176 commentStart[1] ==
'/' &&
4177 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4178 commentStart[3] ==
'<') {
4180 }
else if (commentStart[0] ==
'/' &&
4181 commentStart[1] ==
'*' &&
4182 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4183 commentStart[3] ==
'<') {
4187 commentStart += skipChars;
4190 while ( *commentStart && isspace(*commentStart)
4191 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4194 const char* commentEnd = commentStart;
4196 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4202 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4208 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4209 *loc = sourceLocation.getLocWithOffset(offset - 1);
4212 return llvm::StringRef(commentStart, commentEnd - commentStart);
4223 clang::SourceLocation *loc,
4224 const cling::Interpreter &interpreter)
4226 using namespace clang;
4227 SourceLocation commentSLoc;
4230 Sema& sema = interpreter.getCI()->getSema();
4232 const Decl* DeclFileLineDecl
4233 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4234 cling::LookupHelper::NoDiagnostics);
4235 if (!DeclFileLineDecl)
return llvm::StringRef();
4238 SourceLocation maybeMacroLoc = DeclFileLineDecl->getLocation();
4239 bool isClassDefMacro = maybeMacroLoc.isMacroID() && sema.findMacroSpelling(maybeMacroLoc,
"ClassDef");
4240 if (isClassDefMacro) {
4242 if (comment.size()) {
4249 return llvm::StringRef();
4261 if (rawtype->isElaboratedTypeSpecifier() ) {
4262 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4264 if (rawtype->isArrayType()) {
4265 rawtype = type.getTypePtr()->getBaseElementTypeUnsafe ();
4267 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4269 clang::QualType pointee;
4270 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4272 rawtype = pointee.getTypePtr();
4274 if (rawtype->isElaboratedTypeSpecifier() ) {
4275 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4277 if (rawtype->isArrayType()) {
4278 rawtype = rawtype->getBaseElementTypeUnsafe ();
4282 if (rawtype->isArrayType()) {
4283 rawtype = rawtype->getBaseElementTypeUnsafe ();
4304 static const char *names[] =
4305 {
"shared_ptr",
"__shared_ptr",
4306 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4307 llvm::StringRef clname(cl.getName());
4308 for(
auto &&name : names) {
4309 if (clname == name)
return true;
4319 const clang::CXXRecordDecl ¤tCl)
4322 if (&cl == ¤tCl)
return true;
4324 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4327 if (
NULL == previous){
4346 const clang::CXXRecordDecl *thisDecl =
4347 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4351 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4356 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4389 using namespace clang;
4390 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4391 bool VisitTypedefType(
const TypedefType* TD) {
4394 bool VisitArrayType(
const ArrayType* AT) {
4395 return Visit(AT->getElementType().getTypePtr());
4397 bool VisitDecltypeType(
const DecltypeType* DT) {
4398 return Visit(DT->getUnderlyingType().getTypePtr());
4400 bool VisitPointerType(
const PointerType* PT) {
4401 return Visit(PT->getPointeeType().getTypePtr());
4403 bool VisitReferenceType(
const ReferenceType* RT) {
4404 return Visit(RT->getPointeeType().getTypePtr());
4406 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4407 return Visit(STST->getReplacementType().getTypePtr());
4409 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4410 for (
int I = 0,
N = TST->getNumArgs();
I <
N; ++
I) {
4411 const TemplateArgument& TA = TST->getArg(
I);
4413 && Visit(TA.getAsType().getTypePtr()))
4418 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4421 bool VisitTypeOfType(
const TypeOfType* TOT) {
4422 return TOT->getUnderlyingType().getTypePtr();
4424 bool VisitElaboratedType(
const ElaboratedType* ET) {
4425 NestedNameSpecifier* NNS = ET->getQualifier();
4427 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4428 if (Visit(NNS->getAsType()))
4431 NNS = NNS->getPrefix();
4433 return Visit(ET->getNamedType().getTypePtr());
4448 if (!instance)
return input;
4454 using namespace llvm;
4455 using namespace clang;
4456 const clang::ASTContext &Ctxt = instance->getAsCXXRecordDecl()->getASTContext();
4459 const clang::ElaboratedType* etype
4460 = llvm::dyn_cast<clang::ElaboratedType>(input.getTypePtr());
4464 clang::Qualifiers scope_qualifiers = input.getLocalQualifiers();
4465 assert(instance->getAsCXXRecordDecl()!=0 &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4467 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),instance);
4468 clang::QualType subTy =
ReSubstTemplateArg(clang::QualType(etype->getNamedType().getTypePtr(),0),instance);
4470 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4471 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4475 QualType QT = input;
4479 if (isa<clang::PointerType>(QT.getTypePtr())) {
4481 Qualifiers quals = QT.getQualifiers();
4484 if (nQT == QT->getPointeeType())
return QT;
4486 QT = Ctxt.getPointerType(nQT);
4488 QT = Ctxt.getQualifiedType(QT, quals);
4494 if (isa<ReferenceType>(QT.getTypePtr())) {
4496 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4497 Qualifiers quals = QT.getQualifiers();
4500 if (nQT == QT->getPointeeType())
return QT;
4504 QT = Ctxt.getLValueReferenceType(nQT);
4506 QT = Ctxt.getRValueReferenceType(nQT);
4508 QT = Ctxt.getQualifiedType(QT, quals);
4514 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4516 Qualifiers quals = QT.getQualifiers();
4518 if (isa<ConstantArrayType>(QT.getTypePtr())) {
4519 const ConstantArrayType *arr = dyn_cast<ConstantArrayType>(QT.getTypePtr());
4523 if (newQT == arr->getElementType())
return QT;
4524 QT = Ctxt.getConstantArrayType (newQT,
4526 arr->getSizeModifier(),
4527 arr->getIndexTypeCVRQualifiers());
4529 }
else if (isa<DependentSizedArrayType>(QT.getTypePtr())) {
4530 const DependentSizedArrayType *arr = dyn_cast<DependentSizedArrayType>(QT.getTypePtr());
4534 if (newQT == QT)
return QT;
4535 QT = Ctxt.getDependentSizedArrayType (newQT,
4537 arr->getSizeModifier(),
4538 arr->getIndexTypeCVRQualifiers(),
4539 arr->getBracketsRange());
4541 }
else if (isa<IncompleteArrayType>(QT.getTypePtr())) {
4542 const IncompleteArrayType *arr
4543 = dyn_cast<IncompleteArrayType>(QT.getTypePtr());
4547 if (newQT == arr->getElementType())
return QT;
4548 QT = Ctxt.getIncompleteArrayType (newQT,
4549 arr->getSizeModifier(),
4550 arr->getIndexTypeCVRQualifiers());
4552 }
else if (isa<VariableArrayType>(QT.getTypePtr())) {
4553 const VariableArrayType *arr
4554 = dyn_cast<VariableArrayType>(QT.getTypePtr());
4558 if (newQT == arr->getElementType())
return QT;
4559 QT = Ctxt.getVariableArrayType (newQT,
4561 arr->getSizeModifier(),
4562 arr->getIndexTypeCVRQualifiers(),
4563 arr->getBracketsRange());
4567 QT = Ctxt.getQualifiedType(QT, quals);
4572 etype = llvm::dyn_cast<clang::ElaboratedType>(instance);
4574 instance = etype->getNamedType().getTypePtr();
4575 if (!instance)
return input;
4578 const clang::TemplateSpecializationType* TST
4579 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instance);
4581 if (!TST)
return input;
4583 const clang::ClassTemplateSpecializationDecl* TSTdecl
4584 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instance->getAsCXXRecordDecl());
4586 const clang::SubstTemplateTypeParmType *substType
4587 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(input.getTypePtr());
4591 const clang::ClassTemplateDecl *replacedCtxt = 0;
4593 const clang::DeclContext *replacedDeclCtxt = substType->getReplacedParameter()->getDecl()->getDeclContext();
4594 const clang::CXXRecordDecl *decl = llvm::dyn_cast<clang::CXXRecordDecl>(replacedDeclCtxt);
4595 unsigned int index = substType->getReplacedParameter()->getIndex();
4598 if (decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4599 const clang::ClassTemplatePartialSpecializationDecl *spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(decl);
4601 unsigned int depth = substType->getReplacedParameter()->getDepth();
4603 const TemplateArgument *instanceArgs = spec->getTemplateArgs().data();
4604 unsigned int instanceNArgs = spec->getTemplateArgs().size();
4608 for(
unsigned int A = 0;
A < instanceNArgs; ++
A) {
4610 clang::QualType argQualType = instanceArgs[
A].getAsType();
4612 const clang::TemplateTypeParmType *replacementType;
4614 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(argQualType);
4616 if (!replacementType) {
4617 const clang::SubstTemplateTypeParmType *argType
4618 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(argQualType);
4620 clang::QualType replacementQT = argType->getReplacementType();
4621 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(replacementQT);
4624 if (replacementType &&
4625 depth == replacementType->getDepth() &&
4626 index == replacementType->getIndex() )
4633 replacedCtxt = spec->getSpecializedTemplate();
4635 replacedCtxt = decl->getDescribedClassTemplate();
4638 replacedCtxt = llvm::dyn_cast<clang::ClassTemplateDecl>(replacedDeclCtxt);
4641 if (replacedCtxt->getCanonicalDecl() == TSTdecl->getSpecializedTemplate()->getCanonicalDecl()
4643 substType->getReplacedParameter()->getDecl()
4644 == TSTdecl->getSpecializedTemplate ()->getTemplateParameters()->getParam(index))
4646 if ( index >= TST->getNumArgs() ) {
4653 return TST->getArg(index).getAsType();
4658 const clang::TemplateSpecializationType* inputTST
4659 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(input.getTypePtr());
4660 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4663 bool mightHaveChanged =
false;
4664 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4665 for(clang::TemplateSpecializationType::iterator
I = inputTST->begin(),
E = inputTST->end();
4668 desArgs.push_back(*
I);
4672 clang::QualType SubTy =
I->getAsType();
4674 if (llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4675 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4677 mightHaveChanged = SubTy != newSubTy;
4678 if (!newSubTy.isNull()) {
4679 desArgs.push_back(clang::TemplateArgument(newSubTy));
4682 desArgs.push_back(*
I);
4686 if (mightHaveChanged) {
4687 clang::Qualifiers qualifiers = input.getLocalQualifiers();
4688 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4691 inputTST->getCanonicalTypeInternal());
4692 input = astCtxt.getQualifiedType(input, qualifiers);
4704 if ( nArgsToRemove == 0 || name ==
"")
4709 const unsigned int length = name.length();
4711 unsigned int nArgsRemoved=0;
4712 unsigned int nBraces=0;
4714 while (nArgsRemoved!=nArgsToRemove && cur<length){
4716 if (c ==
'<') nBraces++;
4717 if (c ==
'>') nBraces--;
4718 if (c ==
',' && nBraces==1 ) nArgsRemoved++;
4722 name = name.substr(0,cur)+
">";
4732 static const char *stls[] =
4733 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4734 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",0};
4747 for(
int k=1;stls[k];k++) {
if (type.equals(stls[k]))
return values[k];}
4758 TND = TND->getMostRecentDecl();
4759 while (TND && !(TND->hasAttrs()))
4760 TND = TND->getPreviousDecl();
4772 TD = TD->getMostRecentDecl();
4773 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4774 TD = TD->getPreviousDecl();
4783 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4785 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4786 if (!enclosingNamespaceDeclCtxt)
return;
4788 const clang::NamespaceDecl* enclosingNamespace =
4789 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4790 if (!enclosingNamespace)
return;
4792 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4793 enclosingNamespace->isInline()));
4803 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4805 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4808 if (!enclosingNamespaceDeclCtxt) {
4814 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4815 if (!enclosingNamespace)
return;
4818 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4819 enclosingNamespace->isInline()));
4830 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4832 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4833 if (!enclosingDeclCtxt)
return 0;
4835 unsigned int scopeType;
4837 if (
auto enclosingNamespacePtr =
4838 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4839 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4840 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4844 if (
auto enclosingClassPtr =
4845 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4846 return enclosingClassPtr;
4859 std::string::size_type beginVar = 0;
4860 std::string::size_type endVar = 0;
4861 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4862 && beginVar + 1 < txt.length()) {
4863 std::string::size_type beginVarName = beginVar + 1;
4864 std::string::size_type endVarName = std::string::npos;
4865 if (txt[beginVarName] ==
'(') {
4867 endVarName = txt.find(
')', beginVarName);
4869 if (endVarName == std::string::npos) {
4871 varname, txt.c_str() + beginVar);
4874 endVar = endVarName + 1;
4877 beginVarName = beginVar + 1;
4878 endVarName = beginVarName;
4879 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
4881 endVar = endVarName;
4884 const char* val = getenv(txt.substr(beginVarName,
4885 endVarName - beginVarName).c_str());
4888 txt.replace(beginVar, endVar - beginVar, val);
4889 int lenval = strlen(val);
4890 int delta = lenval - (endVar - beginVar);
4894 beginVar = endVar + 1;
4906 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
4910 std::istringstream envInclPathsStream(envInclPath);
4911 std::string inclPath;
4912 while (std::getline(envInclPathsStream, inclPath,
':')) {
4915 if (!inclPath.empty()) {
4916 clingArgs.push_back(
"-I");
4917 clingArgs.push_back(inclPath);
4928 size_t start_pos = 0;
4933 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
4934 str.replace(start_pos, from.length(), to);
4935 start_pos += to.length();
4936 if (recurse) changed =
true;
4949 static const std::string gPathSeparator (
"\\");
4951 static const std::string gPathSeparator (
"/");
4953 return gPathSeparator;
4960 if (theString.size() < theSubstring.size())
return false;
4961 const unsigned int theSubstringSize = theSubstring.size();
4962 return 0 == theString.compare(theString.size() - theSubstringSize,
4971 if (theString.size() < theSubstring.size())
return false;
4972 const unsigned int theSubstringSize = theSubstring.size();
4973 return 0 == theString.compare(0,
4983 clang::Sema &sema = interp.getSema();
4984 cling::Transaction theTransaction(sema);
4985 std::set<clang::Decl *> addedDecls;
4986 for (
auto decl : decls) {
4988 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
4989 theTransaction.append(ncDecl);
4991 std::string newFwdDecl;
4992 llvm::raw_string_ostream llvmOstr(newFwdDecl);
4993 interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr,
true,
nullptr, ignoreFiles);
5006 std::string& defString)
5018 std::string& defString)
5020 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5023 if (rcdPtr)
return rcdPtr;
5026 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5028 std::string scopeName;
5029 std::string scopeContent;
5030 unsigned int scopeIndex;
5031 for (
auto const & encScope : enclosingNamespaces){
5032 scopeIndex = encScope.second;
5033 scopeName = encScope.first;
5034 scopeContent =
" { " + defString +
" }";
5035 defString = scopeType[scopeIndex] +
5057 const clang::TemplateParameterList& tmplParamList,
5058 const cling::Interpreter& interpreter)
5060 static const char* paramPackWarning=
"Template parameter pack found: autoload of variadic templates is not supported yet.\n";
5063 for (
auto prmIt = tmplParamList.begin();
5064 prmIt != tmplParamList.end(); prmIt++){
5066 if (prmIt != tmplParamList.begin())
5067 templateArgs +=
", ";
5069 auto nDecl = *prmIt;
5070 std::string typeName;
5072 if(nDecl->isParameterPack ()){
5078 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5079 typeName =
"typename " + (*prmIt)->getNameAsString();
5082 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5083 auto theType = nttpd->getType();
5086 if (theType.getAsString().find(
"enum") != std::string::npos){
5087 std::string astDump;
5088 llvm::raw_string_ostream ostream(astDump);
5089 nttpd->dump(ostream);
5091 ROOT::TMetaUtils::Warning(0,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5100 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5103 std::string astDump;
5104 llvm::raw_string_ostream ostream(astDump);
5105 ttpd->dump(ostream);
5107 ROOT::TMetaUtils::Error(0,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5112 templateArgs += typeName;
5123 const cling::Interpreter& interpreter,
5124 std::string& defString)
5126 std::string templatePrefixString;
5127 auto tmplParamList= templDecl.getTemplateParameters();
5128 if (!tmplParamList){
5130 "Cannot extract template parameter list for %s",
5131 templDecl.getNameAsString().c_str());
5138 "Problems with arguments for forward declaration of class %s\n",
5139 templDecl.getNameAsString().c_str());
5142 templatePrefixString =
"template " + templatePrefixString +
" ";
5144 defString = templatePrefixString +
"class " + templDecl.getNameAsString();
5145 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5159 std::string& argFwdDecl,
5160 const cling::Interpreter& interpreter,
5161 bool acceptStl=
false)
5169 auto argQualType = arg.getAsType();
5172 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5174 auto argTypePtr = argQualType.getTypePtr();
5177 if (llvm::isa<clang::EnumType>(argTypePtr)){
5182 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5187 if (llvm::isa<clang::TypedefType>(argTypePtr)){
5188 auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr);
5193 if (llvm::isa<clang::RecordType>(argQualType)){
5195 auto argRecTypePtr = llvm::cast<clang::RecordType>(argTypePtr);
5196 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5211 const cling::Interpreter& interpreter,
5212 std::string& defString,
5220 if (!recordDecl.getIdentifier())
5224 std::string argsFwdDecl;
5226 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5227 std::string argFwdDecl;
5229 std::cout <<
"Class " << recordDecl.getNameAsString()
5230 <<
" is a template specialisation. Treating its arguments.\n";
5231 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5234 std::cout <<
" o Template argument ";
5236 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5238 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5245 argsFwdDecl+=argFwdDecl;
5249 defString=argsFwdDecl;
5254 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5257 defString = argsFwdDecl +
"\n" + defString;
5262 defString =
"class " + recordDecl.getNameAsString() +
";";
5263 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5271 defString = argsFwdDecl +
"\n" + defString;
5282 const cling::Interpreter& interpreter,
5283 std::string& fwdDeclString,
5284 std::unordered_set<std::string>* fwdDeclSetPtr)
5286 std::string buffer = tdnDecl.getNameAsString();
5287 std::string underlyingName;
5288 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5289 if (
const clang::TagType* TT
5290 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5291 if (clang::NamedDecl* ND = TT->getDecl()) {
5292 if (!ND->getIdentifier()) {
5306 if (underlyingName.find(
">::") != std::string::npos)
5309 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5321 auto& ctxt = tdnDecl.getASTContext();
5322 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5324 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5325 std::string tdnFwdDecl;
5326 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5331 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5332 fwdDeclString+=tdnFwdDecl;
5333 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5334 std::string classFwdDecl;
5336 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: " 5337 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5346 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5347 fwdDeclString+=classFwdDecl;
5350 fwdDeclString+=buffer;
5362 std::string& valAsString,
5363 const clang::PrintingPolicy& ppolicy)
5365 auto defArgExprPtr = par.getDefaultArg();
5366 auto& ctxt = par.getASTContext();
5367 if(!defArgExprPtr->isEvaluatable(ctxt)){
5371 auto defArgType = par.getType();
5374 if (defArgType->isBooleanType()){
5376 defArgExprPtr->EvaluateAsBooleanCondition (result,ctxt);
5377 valAsString=std::to_string(result);
5382 if (defArgType->isIntegerType()){
5384 defArgExprPtr->EvaluateAsInt(result,ctxt);
5385 auto uintVal = *result.getRawData();
5386 if (result.isNegative()){
5387 long long int intVal=uintVal*-1;
5388 valAsString=std::to_string(intVal);
5390 valAsString=std::to_string(uintVal);
5397 llvm::raw_string_ostream rso(valAsString);
5398 defArgExprPtr->printPretty(rso,
nullptr,ppolicy);
5399 valAsString = rso.str();
void WriteReadRawRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for ReadRaw rule, the function name is being written to rule["funcname"...
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
std::map< std::string, ROOT::Internal::TSchemaType > MembersTypeMap_t
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
bool equal(double d1, double d2, double stol=10000)
void WriteSchemaList(std::list< SchemaRuleMap_t > &rules, const std::string &listName, std::ostream &output)
Write schema rules.
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members)
Check if given rule contains references to valid data members.
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
std::string GetNameForIO(const std::string &templateInstanceName, TClassEdit::EModType mode=TClassEdit::kNone, bool *hasChanged=nullptr)
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
RooArgSet S(const RooAbsArg &v1)
SchemaRuleClassMap_t gReadRules
static void indent(ostringstream &buf, int indent_level)
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
Type
enumeration specifying the integration types.
void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
void WriteReadRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for Read rule, the function name is being written to rule["funcname"]...
SchemaRuleClassMap_t gReadRawRules
#define dest(otri, vertexptr)