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"
47 #include "cling/Interpreter/LookupHelper.h"
48 #include "cling/Interpreter/Transaction.h"
49 #include "cling/Interpreter/Interpreter.h"
50 #include "cling/Utils/AST.h"
52 #include "llvm/Support/Path.h"
53 #include "llvm/Support/FileSystem.h"
56 #include "../../../interpreter/llvm/src/tools/clang/lib/Sema/HackForDefaultTemplateArg.h"
65 namespace TMetaUtils {
72 class TNormalizedCtxtImpl {
73 using DeclsCont_t = TNormalizedCtxt::Config_t::SkipCollection;
79 TypesCont_t fTypeWithAlternative;
80 static TemplPtrIntMap_t fTemplatePtrArgsToKeepMap;
82 TNormalizedCtxtImpl(
const cling::LookupHelper &lh);
84 const Config_t &GetConfig()
const {
return fConfig; }
85 const TypesCont_t &GetTypeWithAlternative()
const {
return fTypeWithAlternative; }
86 void AddTemplAndNargsToKeep(
const clang::ClassTemplateDecl* templ,
unsigned int i);
87 int GetNargsToKeep(
const clang::ClassTemplateDecl* templ)
const;
88 const TemplPtrIntMap_t GetTemplNargsToKeepMap()
const {
return fTemplatePtrArgsToKeepMap; }
89 void keepTypedef(
const cling::LookupHelper &lh,
const char* name,
90 bool replace =
false);
100 static clang::NestedNameSpecifier* AddDefaultParametersNNS(
const clang::ASTContext& Ctx,
101 clang::NestedNameSpecifier* scope,
102 const cling::Interpreter &interpreter,
104 if (!scope)
return 0;
106 const clang::Type* scope_type = scope->getAsType();
109 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
111 outer_scope = AddDefaultParametersNNS(Ctx, outer_scope, interpreter, normCtxt);
114 clang::QualType addDefault =
117 if (addDefault.getTypePtr() != scope_type)
118 return clang::NestedNameSpecifier::Create(Ctx,outer_scope,
120 addDefault.getTypePtr());
127 static bool CheckDefinition(
const clang::CXXRecordDecl *cl,
const clang::CXXRecordDecl *context)
129 if (!cl->hasDefinition()) {
132 "Missing definition for class %s, please #include its header in the header of %s\n",
133 cl->getName().str().c_str(), context->getName().str().c_str());
136 "Missing definition for class %s\n",
137 cl->getName().str().c_str());
149 static clang::NestedNameSpecifier* ReSubstTemplateArgNNS(
const clang::ASTContext &Ctxt,
150 clang::NestedNameSpecifier *scope,
153 if (!scope)
return 0;
155 const clang::Type* scope_type = scope->getAsType();
157 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
159 outer_scope = ReSubstTemplateArgNNS(Ctxt, outer_scope, instance);
161 clang::QualType substScope =
164 scope = clang::NestedNameSpecifier::Create(Ctxt,outer_scope,
166 substScope.getTypePtr());
175 const clang::BuiltinType * builtin = llvm::dyn_cast<clang::BuiltinType>(type->getCanonicalTypeInternal().getTypePtr());
177 return builtin->isInteger();
185 static bool IsFieldDeclInt(
const clang::FieldDecl *field)
187 return IsTypeInt(field->getType().getTypePtr());
193 static const clang::FieldDecl *GetDataMemberFromAll(
const clang::CXXRecordDecl &cl, llvm::StringRef what)
195 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
198 if (field_iter->getName() ==
what) {
208 static bool CXXRecordDecl__FindOrdinaryMember(
const clang::CXXBaseSpecifier *Specifier,
209 clang::CXXBasePath &Path,
213 clang::RecordDecl *BaseRecord = Specifier->getType()->getAs<clang::RecordType>()->getDecl();
215 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(BaseRecord);
216 if (clxx == 0)
return false;
218 const clang::FieldDecl *found = GetDataMemberFromAll(*clxx,(
const char*)Name);
222 clang::NamedDecl* NonConstFD =
const_cast<clang::FieldDecl*
>(found);
223 clang::NamedDecl** BaseSpecFirstHack
224 =
reinterpret_cast<clang::NamedDecl**
>(NonConstFD);
225 Path.Decls = clang::DeclContextLookupResult(BaseSpecFirstHack, 1);
250 static const clang::FieldDecl *GetDataMemberFromAllParents(
const clang::CXXRecordDecl &cl,
const char *what)
252 clang::CXXBasePaths Paths;
253 Paths.setOrigin(const_cast<clang::CXXRecordDecl*>(&cl));
254 if (cl.lookupInBases(&CXXRecordDecl__FindOrdinaryMember,
255 (
void*) const_cast<char*>(what),
258 clang::CXXBasePaths::paths_iterator
iter = Paths.begin();
259 if (iter != Paths.end()) {
261 const clang::FieldDecl *found = (clang::FieldDecl *)iter->Decls.data();
269 cling::LookupHelper::DiagSetting ToLHDS(
bool wantDiags) {
271 ? cling::LookupHelper::WithDiagnostics
272 : cling::LookupHelper::NoDiagnostics;
279 namespace TMetaUtils {
285 void TNormalizedCtxtImpl::AddTemplAndNargsToKeep(
const clang::ClassTemplateDecl* templ,
288 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
289 "Tring to specify a number of template arguments to keep for a null pointer. Exiting without assigning any value.\n");
293 const clang::ClassTemplateDecl* canTempl = templ->getCanonicalDecl();
295 if(fTemplatePtrArgsToKeepMap.count(canTempl)==1 &&
296 fTemplatePtrArgsToKeepMap[canTempl]!=(int)i){
297 const std::string templateName (canTempl->getNameAsString());
298 const std::string i_str (std::to_string(i));
299 const std::string previousArgsToKeep(std::to_string(fTemplatePtrArgsToKeepMap[canTempl]));
300 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
301 "Tring to specify for template %s %s arguments to keep, while before this number was %s\n",
302 canTempl->getNameAsString().c_str(),
304 previousArgsToKeep.c_str());
307 fTemplatePtrArgsToKeepMap[canTempl]=i;
314 int TNormalizedCtxtImpl::GetNargsToKeep(
const clang::ClassTemplateDecl* templ)
const{
315 const clang::ClassTemplateDecl* constTempl = templ->getCanonicalDecl();
316 auto thePairPtr = fTemplatePtrArgsToKeepMap.find(constTempl);
317 int nArgsToKeep = (thePairPtr != fTemplatePtrArgsToKeepMap.end() ) ? thePairPtr->second : -1;
325 fImpl(new TNormalizedCtxtImpl(lh))
329 fImpl(new TNormalizedCtxtImpl(*other.fImpl))
336 return fImpl->GetConfig();
339 return fImpl->GetTypeWithAlternative();
343 return fImpl->AddTemplAndNargsToKeep(templ, i);
347 return fImpl->GetNargsToKeep(templ);
350 return fImpl->GetTemplNargsToKeepMap();
355 return fImpl->keepTypedef(lh, name, replace);
365 const clang::RecordDecl *decl,
368 bool rRequestNoInputOperator,
369 bool rRequestOnlyTClass,
370 int rRequestedVersionNumber,
371 const cling::Interpreter &interpreter,
373 fRuleIndex(index), fDecl(decl), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
374 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestedVersionNumber)
385 const clang::RecordDecl *decl,
386 const char *requestName,
387 unsigned int nTemplateArgsToSkip,
390 bool rRequestNoInputOperator,
391 bool rRequestOnlyTClass,
392 int rRequestVersionNumber,
393 const cling::Interpreter &interpreter,
395 fRuleIndex(index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
396 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
405 "Could not remove the requested template arguments.\n");
414 const clang::RecordDecl *decl,
415 const char *requestName,
418 bool rRequestNoInputOperator,
419 bool rRequestOnlyTClass,
420 int rRequestVersionNumber,
421 const cling::Interpreter &interpreter,
423 fRuleIndex(index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
424 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
437 const clang::RecordDecl *decl,
438 const char *requestName,
441 bool rRequestNoInputOperator,
442 bool rRequestOnlyTClass,
443 int rRequestVersionNumber,
444 const cling::Interpreter &interpreter,
446 fRuleIndex(index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer), fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
455 if (requestName && requestName[0]) {
471 ExistingTypeCheck_t existingTypeCheck,
472 AutoParse_t autoParse,
473 const int* pgDebug ):
474 fInterpreter(&interpreter),fNormalizedCtxt(&normCtxt),
475 fExistingTypeCheck(existingTypeCheck),
476 fAutoParse(autoParse), fPDebug(pgDebug)
487 if (tname.empty())
return false;
497 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
498 clang::QualType
t = lh.findType(nameLong, ToLHDS(
WantDiags()));
501 if (!dest.isNull() && (dest !=
t)) {
504 dest.getAsStringInternal(nameLong,
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
512 const std::string &nameLong)
514 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
515 clang::QualType
t = lh.findType(nondef.c_str(), ToLHDS(
WantDiags()));
518 if (!dest.isNull() && (dest !=
t) &&
519 nameLong == t.getAsString(
fInterpreter->getCI()->getASTContext().getPrintingPolicy()))
529 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
530 const clang::Decl *scope = lh.findScope(base.c_str(), ToLHDS(
WantDiags()), 0);
537 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(scope);
538 isInlined = nsdecl && nsdecl->isInline();
549 if (tname.empty())
return false;
557 return ! result.empty();
566 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
567 clang::QualType
t = lh.findType(tname.c_str(), ToLHDS(
WantDiags()));
574 if (!dest.isNull() && dest !=
t) {
578 clang::PrintingPolicy policy(
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
579 policy.SuppressTagKeyword =
true;
580 policy.SuppressScope =
true;
586 dest.getAsStringInternal(result, policy);
589 if (strncmp(result.c_str(),
"const ", 6) == 0) {
592 if (strncmp(result.c_str()+
offset,
"std::", 5) == 0) {
593 result.erase(offset,5);
595 for(
unsigned int i = 1; i<result.length(); ++i) {
596 if (result[i]==
's') {
597 if (result[i-1]==
'<' || result[i-1]==
',' || result[i-1]==
' ') {
598 if (result.compare(i,5,
"std::",5) == 0) {
603 if (result[i]==
' ') {
604 if (result[i-1] ==
',') {
607 }
else if ( (i+1) < result.length() &&
608 (result[i+1]==
'*' || result[i+1]==
'&' || result[i+1]==
'[') ) {
633 void ROOT::TMetaUtils::TNormalizedCtxtImpl::keepTypedef(
const cling::LookupHelper &lh,
636 clang::QualType toSkip = lh.findType(name, cling::LookupHelper::WithDiagnostics);
638 const clang::TypedefType *tt = llvm::dyn_cast<clang::TypedefType>(
T);
640 clang::Decl* D = tt->getDecl();
641 fConfig.m_toSkip.insert(D);
643 clang::QualType canon = toSkip->getCanonicalTypeInternal();
644 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),
T));
646 fTypeWithAlternative.insert(
T);
657 ROOT::TMetaUtils::TNormalizedCtxtImpl::TNormalizedCtxtImpl(
const cling::LookupHelper &lh)
659 keepTypedef(lh,
"Double32_t");
660 keepTypedef(lh,
"Float16_t");
661 keepTypedef(lh,
"Long64_t",
true);
662 keepTypedef(lh,
"ULong64_t",
true);
664 clang::QualType toSkip = lh.findType(
"string", cling::LookupHelper::WithDiagnostics);
665 if (
const clang::TypedefType* TT
666 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
667 fConfig.m_toSkip.insert(TT->getDecl());
669 toSkip = lh.findType(
"std::string", cling::LookupHelper::WithDiagnostics);
670 if (!toSkip.isNull()) {
671 if (
const clang::TypedefType* TT
672 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
673 fConfig.m_toSkip.insert(TT->getDecl());
675 clang::QualType canon = toSkip->getCanonicalTypeInternal();
676 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),toSkip.getTypePtr()));
681 TNCtxtFullQual::TemplPtrIntMap_t TNCtxtFullQual::fTemplatePtrArgsToKeepMap=TNCtxtFullQual::TemplPtrIntMap_t{};
689 return (cl.getKind() == clang::Decl::ClassTemplatePartialSpecialization
690 || cl.getKind() == clang::Decl::ClassTemplateSpecialization);
697 const cling::Interpreter& interp)
699 clang::Sema*
S = &interp.getSema();
700 const clang::NamedDecl* ND = cling::utils::Lookup::Named(S, name, cl);
701 if (ND == (clang::NamedDecl*)-1)
702 return (clang::FunctionDecl*)-1;
703 return llvm::dyn_cast_or_null<clang::FunctionDecl>(ND);
709 const clang::CXXRecordDecl *
713 const cling::LookupHelper& lh = interp.getLookupHelper();
716 const clang::CXXRecordDecl *
result
717 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
718 (lh.findScope(name, cling::LookupHelper::NoDiagnostics, resultType));
720 std::string std_name(
"std::");
724 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
725 (lh.findScope(std_name, cling::LookupHelper::NoDiagnostics, resultType));
735 clang::QualType qType(cl->getTypeForDecl(),0);
743 clang::Sema&
S = interp.getCI()->getSema();
746 cling::Interpreter::PushTransactionRAII RAII(const_cast<cling::Interpreter*>(&interp));
747 return S.RequireCompleteType( Loc, Type , 0);
753 const clang::CXXRecordDecl *context,
const cling::Interpreter &interp)
759 if (!cl->getDefinition() || !cl->isCompleteDefinition()) {
763 if (!CheckDefinition(cl, context) || !CheckDefinition(base, context)) {
767 if (!base->hasDefinition()) {
771 return cl->isDerivedFrom(base);
783 const clang::NamedDecl *base
787 return IsBase(CRD, llvm::dyn_cast<clang::CXXRecordDecl>( base ),
788 llvm::dyn_cast<clang::CXXRecordDecl>(m.getDeclContext()),interp);
796 const clang::NamedDecl &forcontext,
797 const clang::QualType &qti,
798 const char *R__t,
int rwmode,
799 const cling::Interpreter &interp,
802 static const clang::CXXRecordDecl *TObject_decl
805 kBIT_ISTOBJECT = 0x10000000,
806 kBIT_HASSTREAMER = 0x20000000,
807 kBIT_ISSTRING = 0x40000000,
809 kBIT_ISPOINTER = 0x00001000,
810 kBIT_ISFUNDAMENTAL = 0x00000020,
811 kBIT_ISENUM = 0x00000008
824 clang::CXXRecordDecl *cxxtype = rawtype->getAsCXXRecordDecl() ;
826 int isTObj = cxxtype && (
IsBase(cxxtype,TObject_decl,
nullptr,interp) || rawname ==
"TObject");
830 if (ti.isPointerType()) kase |= kBIT_ISPOINTER;
831 if (rawtype->isFundamentalType()) kase |= kBIT_ISFUNDAMENTAL;
832 if (rawtype->isEnumeralType()) kase |= kBIT_ISENUM;
835 if (isTObj) kase |= kBIT_ISTOBJECT;
836 if (isStre) kase |= kBIT_HASSTREAMER;
837 if (tiName ==
"string") kase |= kBIT_ISSTRING;
838 if (tiName ==
"string*") kase |= kBIT_ISSTRING;
842 tcl =
" internal error in rootcling ";
848 if (R__t) finalString <<
" " << tiName <<
" " << R__t <<
";" << std::endl;
851 case kBIT_ISFUNDAMENTAL:
853 finalString <<
" R__b >> " << R__t <<
";" << std::endl;
856 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
858 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
867 finalString <<
" Int_t readtemp;" << std::endl
868 <<
" R__b >> readtemp;" << std::endl
869 <<
" " << R__t <<
" = static_cast<" << tiName <<
">(readtemp);" << std::endl;
872 case kBIT_HASSTREAMER:
873 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
875 finalString <<
" " << R__t <<
".Streamer(R__b);" << std::endl;
878 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
881 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
882 if (cxxtype && cxxtype->isAbstract()) {
883 finalString <<
" R__ASSERT(0);// " << objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
885 finalString <<
" " << R__t <<
" = new " << objType <<
";" << std::endl
886 <<
" " << R__t <<
"->Streamer(R__b);" << std::endl;
888 finalString <<
" } else {" << std::endl
889 <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl
890 <<
" }" << std::endl;
895 finalString <<
" {TString R__str;" << std::endl
896 <<
" R__str.Streamer(R__b);" << std::endl
897 <<
" " << R__t <<
" = R__str.Data();}" << std::endl;
900 case kBIT_ISSTRING|kBIT_ISPOINTER:
902 finalString <<
" {TString R__str;" << std::endl
903 <<
" R__str.Streamer(R__b);" << std::endl
904 <<
" " << R__t <<
" = new string(R__str.Data());}" << std::endl;
909 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
914 finalString <<
" R__b.StreamObject(&" << R__t <<
"," << tcl <<
");" << std::endl;
922 case kBIT_ISFUNDAMENTAL:
923 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
925 finalString <<
" R__b << " << R__t <<
";" << std::endl;
930 finalString <<
" { void *ptr_enum = (void*)&" << R__t <<
";\n";
931 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
934 case kBIT_HASSTREAMER:
935 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
937 finalString <<
" ((" << objType <<
"&)" << R__t <<
").Streamer(R__b);" << std::endl;
940 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
942 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
947 finalString <<
" {TString R__str(" << R__t <<
".c_str());" << std::endl
948 <<
" R__str.Streamer(R__b);};" << std::endl;
951 case kBIT_ISSTRING|kBIT_ISPOINTER:
953 finalString <<
" {TString R__str(" << R__t <<
"->c_str());" << std::endl
954 <<
" R__str.Streamer(R__b);}" << std::endl;
959 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
964 finalString <<
" R__b.StreamObject((" << objType <<
"*)&" << R__t <<
"," << tcl <<
");" << std::endl;
976 const char *arg = ioctortype.
GetName();
977 if ( (arg == 0 || arg[0] ==
'\0') && !cl->hasUserDeclaredConstructor() ) {
981 if (ioctortype.
GetType() ==0 && (arg == 0 || arg[0] ==
'\0')) {
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() == 0) {
995 if ( (*
iter->param_begin())->hasDefaultArg()) {
1001 for(clang::CXXRecordDecl::ctor_iterator
iter = cl->ctor_begin(), end = cl->ctor_end();
1005 if (
iter->getAccess() != clang::AS_public)
1009 if (
iter->getNumParams() == 1) {
1010 clang::QualType argType( (*
iter->param_begin())->getType() );
1011 argType = argType.getDesugaredType(cl->getASTContext());
1013 auto ioCtorCategory = EIOCtorCategory::kAbsent;
1014 if (argType->isPointerType()) {
1015 ioCtorCategory = EIOCtorCategory::kIOPtrType;
1016 argType = argType->getPointeeType();
1017 }
else if (argType->isReferenceType()){
1018 ioCtorCategory = EIOCtorCategory::kIORefType;
1019 argType = argType.getNonReferenceType();
1021 if (ioCtorCategory != EIOCtorCategory::kAbsent) {
1022 argType = argType.getDesugaredType(cl->getASTContext());
1023 const clang::CXXRecordDecl *argDecl = argType->getAsCXXRecordDecl();
1024 if (argDecl && ioctortype.
GetType()) {
1025 if (argDecl->getCanonicalDecl() == ioctortype.
GetType()->getCanonicalDecl()) {
1026 return ioCtorCategory;
1029 std::string realArg = argType.getAsString();
1030 std::string clarg(
"class ");
1032 if (realArg == clarg) {
1033 return ioCtorCategory;
1042 return EIOCtorCategory::kAbsent;
1049 const char *method,
const char *proto,
1050 const cling::Interpreter &interp,
1053 const clang::FunctionDecl* funcD
1054 = interp.getLookupHelper().findFunctionProto(cinfo, method, proto,
1055 diagnose ? cling::LookupHelper::WithDiagnostics
1056 : cling::LookupHelper::NoDiagnostics);
1058 return llvm::dyn_cast<
const clang::CXXMethodDecl>(funcD);
1067 namespace TMetaUtils {
1070 const cling::LookupHelper& lh = interp.getLookupHelper();
1073 clang::QualType instanceType = lh.findType(type_of_arg, cling::LookupHelper::WithDiagnostics);
1074 if (!instanceType.isNull())
1075 fArgType = instanceType->getAsCXXRecordDecl();
1089 const cling::Interpreter &interp)
1091 if (cl->isAbstract())
return false;
1093 for (RConstructorTypes::const_iterator ctorTypeIt = ctorTypes.begin();
1094 ctorTypeIt!=ctorTypes.end(); ++ctorTypeIt) {
1098 if (EIOCtorCategory::kAbsent == ioCtorCat)
1101 std::string proto( ctorTypeIt->GetName() );
1102 bool defaultCtor = proto.empty();
1108 if (EIOCtorCategory::kIOPtrType == ioCtorCat){
1110 }
else if (EIOCtorCategory::kIORefType == ioCtorCat) {
1114 arg +=
")nullptr )";
1117 const clang::CXXMethodDecl *method
1119 cling::LookupHelper::NoDiagnostics);
1120 if (method && method->getAccess() != clang::AS_public) {
1135 if (!cl)
return false;
1137 if (cl->hasUserDeclaredDestructor()) {
1139 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1141 return (dest->getAccess() == clang::AS_public);
1153 const char *methodname,
1155 const cling::Interpreter &interp,
1158 const clang::CXXMethodDecl *method
1160 diagnose ? cling::LookupHelper::WithDiagnostics
1161 : cling::LookupHelper::NoDiagnostics);
1162 return (method && method->getAccess() == clang::AS_public);
1173 const char *proto =
"TDirectory*";
1174 const char *name =
"DirectoryAutoAdd";
1188 const char *proto =
"TCollection*,TFileMergeInfo*";
1189 const char *name =
"Merge";
1202 const char *proto =
"TCollection*";
1203 const char *name =
"Merge";
1218 const char *proto =
"TFileMergeInfo*";
1219 const char *name =
"ResetAfterMerge";
1229 const clang::CXXRecordDecl* clxx,
1230 const cling::Interpreter &interp,
1233 static const char *proto =
"TBuffer&";
1235 const clang::CXXMethodDecl *method
1237 cling::LookupHelper::NoDiagnostics);
1238 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1240 return (method && method->getDeclContext() == clxx_as_context
1248 const clang::CXXRecordDecl* clxx,
1249 const cling::Interpreter &interp,
1252 static const char *proto =
"TBuffer&,TClass*";
1254 const clang::CXXMethodDecl *method
1256 cling::LookupHelper::NoDiagnostics);
1257 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1259 return (method && method->getDeclContext() == clxx_as_context
1289 clang::QualType qualType(&type,0);
1321 llvm::raw_string_ostream stream(qual_name);
1322 clang::PrintingPolicy policy( cl.getASTContext().getPrintingPolicy() );
1323 policy.SuppressTagKeyword =
true;
1324 policy.SuppressUnwrittenScope =
true;
1326 cl.getNameForDiagnostic(stream,policy,
true);
1329 if ( qual_name ==
"(anonymous " ) {
1330 size_t pos = qual_name.find(
':');
1331 qual_name.erase(0,pos+2);
1347 const clang::Type* declType ( recordDecl.getTypeForDecl() );
1348 clang::QualType qualType(declType,0);
1382 std::stringstream dims;
1383 std::string typenameStr;
1385 const clang::ASTContext& astContext = cl.getASTContext();
1388 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
1396 typenameStr.clear();
1400 clang::QualType fieldType(field_iter->getType());
1401 if (fieldType->isConstantArrayType()) {
1402 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(fieldType.getTypePtr());
1404 dims <<
"[" << arrayType->getSize().getLimitedValue() <<
"]";
1405 fieldType = arrayType->getElementType();
1406 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1416 for(clang::CXXRecordDecl::base_class_const_iterator
iter = cl.bases_begin(), end = cl.bases_end();
1419 std::string basename(
iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1429 const cling::Interpreter &interp,
1432 return interp.getLookupHelper().findFunctionProto(cinfo, method, proto,
1433 diagnose ? cling::LookupHelper::WithDiagnostics
1434 : cling::LookupHelper::NoDiagnostics);
1468 clang::SourceLocation sourceLocation = decl->getLocation();
1469 clang::SourceManager& sourceManager = decl->getASTContext().getSourceManager();
1471 if (!sourceLocation.isValid() ) {
1475 if (!sourceLocation.isFileID()) {
1476 sourceLocation = sourceManager.getExpansionRange(sourceLocation).second;
1479 if (sourceLocation.isValid() && sourceLocation.isFileID()) {
1480 return sourceManager.getLineNumber(sourceManager.getFileID(sourceLocation),sourceManager.getFileOffset(sourceLocation));
1493 while (llvm::isa<clang::PointerType>(instanceType.getTypePtr())
1494 || llvm::isa<clang::ReferenceType>(instanceType.getTypePtr()))
1496 instanceType = instanceType->getPointeeType();
1499 const clang::ElaboratedType* etype
1500 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
1502 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1515 const clang::CXXRecordDecl* clxx = instanceType->getAsCXXRecordDecl();
1516 if (clxx && clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1518 const clang::TemplateSpecializationType* TST
1519 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instanceType.getTypePtr());
1526 for(clang::TemplateSpecializationType::iterator
1527 I = TST->begin(),
E = TST->end();
1545 const cling::Interpreter &interp,
1548 const clang::CXXRecordDecl* clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1549 if (clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return 0;
1551 clang::QualType instanceType = interp.getLookupHelper().findType(cl.
GetNormalizedName(),
1552 cling::LookupHelper::WithDiagnostics);
1553 if (instanceType.isNull()) {
1566 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(attribute);
1571 attrString = annAttr->getAnnotation();
1581 if (substrFound==std::string::npos) {
1586 attrName = attributeStr.substr(0, EndPart1);
1588 attrValue = attributeStr.substr(EndPart1 + separatorLength);
1596 std::string attrString;
1598 if (0!=ret)
return ret;
1606 const std::string& propName,
1607 std::string& propValue)
1609 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1610 attrIt!=decl.attr_end();++attrIt){
1611 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1612 if (!annAttr)
continue;
1614 llvm::StringRef attribute = annAttr->getAnnotation();
1616 if (split.first != propName.c_str())
continue;
1618 propValue = split.second;
1629 const std::string& propName,
1632 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1633 attrIt!=decl.attr_end();++attrIt){
1634 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1635 if (!annAttr)
continue;
1637 llvm::StringRef attribute = annAttr->getAnnotation();
1639 if (split.first != propName.c_str())
continue;
1641 return split.second.getAsInteger(10,propValue);
1652 const clang::CXXRecordDecl *decl,
1653 const cling::Interpreter &interp,
1656 bool& needCollectionProxy)
1660 std::string mappedname;
1662 std::string csymbol = classname;
1670 csymbol.insert(0,
"::");
1677 const cling::LookupHelper& lh = interp.getLookupHelper();
1680 bool isStdNotString = isStd && !isString;
1682 finalString <<
"namespace ROOT {" <<
"\n";
1686 finalString <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();\n"
1687 <<
" static void " << mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1693 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p = 0);" <<
"\n";
1697 finalString <<
" static void *newArray_";
1698 finalString << mappedname.c_str();
1699 finalString <<
"(Long_t size, void *p);";
1700 finalString <<
"\n";
1705 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";
1708 finalString <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1711 finalString <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1714 finalString <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1717 finalString <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1720 finalString <<
" static void reset_" << mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1727 std::string declName;
1729 ROOT::SchemaRuleClassMap_t::iterator rulesIt1 =
ROOT::gReadRules.find( declName.c_str() );
1730 ROOT::SchemaRuleClassMap_t::iterator rulesIt2 =
ROOT::gReadRawRules.find( declName.c_str() );
1741 finalString <<
"\n // Schema evolution read functions\n";
1742 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt1->second.begin();
1743 while( rIt != rulesIt1->second.end() ) {
1750 rIt = rulesIt1->second.erase(rIt);
1758 if( rIt->find(
"code" ) != rIt->end() ) {
1774 finalString <<
"\n // Schema evolution read raw functions\n";
1775 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt2->second.begin();
1776 while( rIt != rulesIt2->second.end() ) {
1783 rIt = rulesIt2->second.erase(rIt);
1791 if( rIt->find(
"code" ) == rIt->end() )
1799 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1801 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " << csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1803 finalString <<
" " << csymbol <<
" *ptr = 0;" <<
"\n";
1807 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " << csymbol <<
" >(0);" <<
"\n";
1810 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol <<
"));" <<
"\n";
1812 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1815 finalString << csymbol <<
"::Class_Version(), ";
1817 finalString <<
"2, ";
1819 finalString <<
"-2, ";
1825 static const char *versionFunc =
"GetClassVersion";
1829 std::string proto = classname +
"*";
1830 const clang::Decl* ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1831 const clang::FunctionDecl *methodinfo
1833 interp, cling::LookupHelper::NoDiagnostics);
1841 finalString <<
"GetClassVersion< ";
1842 finalString << classname.c_str();
1843 finalString <<
" >(), ";
1851 if (filename.length() > 0) {
1852 for (
unsigned int i=0; i<filename.length(); i++) {
1853 if (filename[i]==
'\\') filename[i]=
'/';
1857 <<
"," <<
"\n" <<
" typeid(" << csymbol
1858 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1861 finalString <<
"&" << csymbol <<
"::Dictionary, ";
1863 finalString <<
"&" << mappedname <<
"_Dictionary, ";
1867 TClassTable__kHasCustomStreamerMember = 0x10
1872 rootflag = rootflag | TClassTable__kHasCustomStreamerMember;
1874 finalString <<
"isa_proxy, " << rootflag <<
"," <<
"\n" <<
" sizeof(" << csymbol <<
") );" <<
"\n";
1876 finalString <<
" instance.SetNew(&new_" << mappedname.c_str() <<
");" <<
"\n";
1878 finalString <<
" instance.SetNewArray(&newArray_" << mappedname.c_str() <<
");" <<
"\n";
1881 finalString <<
" instance.SetDelete(&delete_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" << mappedname.c_str() <<
");" <<
"\n";
1884 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" << mappedname.c_str() <<
");" <<
"\n";
1888 finalString <<
" instance.SetStreamerFunc(&streamer_" << mappedname.c_str() <<
");" <<
"\n";
1892 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" << mappedname.c_str() <<
");" <<
"\n";
1895 finalString <<
" instance.SetMerge(&merge_" << mappedname.c_str() <<
");" <<
"\n";
1898 finalString <<
" instance.SetResetAfterMerge(&reset_" << mappedname.c_str() <<
");" <<
"\n";
1901 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
1903 needCollectionProxy =
true;
1904 }
else if (stl != 0 &&
1907 int idx = classname.find(
"<");
1908 int stlType = (idx!=(int)std::string::npos) ?
TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
1909 const char* methodTCP=0;
1914 methodTCP=
"Pushback";
1917 methodTCP=
"Pushfront";
1923 methodTCP=
"MapInsert";
1932 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << methodTCP <<
"< " << classname.c_str() <<
" >()));" <<
"\n";
1934 needCollectionProxy =
true;
1942 finalString <<
"\n" <<
" ::ROOT::AddClassAlternate(\""
1951 finalString <<
"\n" <<
" ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
1955 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<ROOT::Internal::TSchemaHelper> readrules(" << rulesIt1->second.size() <<
");" <<
"\n";
1957 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
1961 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<ROOT::Internal::TSchemaHelper> readrawrules(" << rulesIt2->second.size() <<
");" <<
"\n";
1963 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
1966 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
1970 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " << csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal((" << csymbol <<
"*)0);\n }" <<
"\n";
1973 finalString <<
" // Static variable to force the class initialization" <<
"\n";
1977 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstanceLocal((const " << csymbol <<
"*)0x0); R__UseDummy(_R__UNIQUE_(Init));" <<
"\n";
1980 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n"
1981 <<
" static TClass *" << mappedname <<
"_Dictionary() {\n"
1982 <<
" TClass* theClass ="
1983 <<
"::ROOT::GenerateInitInstanceLocal((const " << csymbol <<
"*)0x0)->GetClass();\n"
1984 <<
" " << mappedname <<
"_TClassManip(theClass);\n";
1985 finalString <<
" return theClass;\n";
1986 finalString <<
" }\n\n";
1990 std::string manipString;
1991 std::string attribute_s;
1992 std::string attrName, attrValue;
1994 bool attrMapExtracted =
false;
1995 if (decl->hasAttrs()){
1997 for (clang::Decl::attr_iterator attrIt = decl->attr_begin();
1998 attrIt!=decl->attr_end();++attrIt){
2005 if (attrName ==
"name" ||
2006 attrName ==
"pattern" ||
2007 attrName ==
"rootmap")
continue;
2013 if (!attrMapExtracted){
2014 manipString+=
" theClass->CreateAttributeMap();\n";
2015 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2016 attrMapExtracted=
true;
2018 manipString+=
" attrMap->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2024 for(clang::CXXRecordDecl::decl_iterator internalDeclIt = decl->decls_begin();
2025 internalDeclIt != decl->decls_end(); ++internalDeclIt){
2026 if (!(!(*internalDeclIt)->isImplicit()
2027 && (clang::isa<clang::FieldDecl>(*internalDeclIt) ||
2028 clang::isa<clang::VarDecl>(*internalDeclIt))))
continue;
2031 if (!internalDeclIt->hasAttrs())
continue;
2033 attrMapExtracted =
false;
2034 bool memberPtrCreated =
false;
2036 for (clang::Decl::attr_iterator attrIt = internalDeclIt->attr_begin();
2037 attrIt!=internalDeclIt->attr_end();++attrIt){
2045 clang::NamedDecl* namedInternalDecl = clang::dyn_cast<clang::NamedDecl> (*internalDeclIt);
2046 if (!namedInternalDecl) {
2050 const std::string memberName(namedInternalDecl->getName());
2051 const std::string cppMemberName=
"theMember_"+memberName;
2054 const std::string dataMemberCreation=
" TDataMember* "+cppMemberName+
" = theClass->GetDataMember(\""+memberName+
"\");\n";
2067 if (!memberPtrCreated){
2068 manipString+=dataMemberCreation;
2069 memberPtrCreated=
true;
2072 if (!attrMapExtracted){
2073 manipString+=
" "+cppMemberName+
"->CreateAttributeMap();\n";
2074 manipString+=
" TDictAttributeMap* memberAttrMap_"+memberName+
"( theMember_"+memberName+
"->GetAttributeMap() );\n";
2075 attrMapExtracted=
true;
2078 manipString+=
" memberAttrMap_"+memberName+
"->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2085 finalString <<
" static void " << mappedname <<
"_TClassManip(TClass* " << (manipString.empty() ?
"":
"theClass") <<
"){\n"
2090 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2100 std::string &clsname,
2101 std::string &nsname,
2102 const clang::CXXRecordDecl *cl)
2112 auto ctxt = cl->getEnclosingNamespaceContext();
2113 while(ctxt && ctxt!=cl && ctxt->isInlineNamespace()) {
2114 ctxt = ctxt->getParent();
2117 const clang::NamedDecl *namedCtxt = llvm::dyn_cast<clang::NamedDecl>(ctxt);
2118 if (namedCtxt && namedCtxt!=cl) {
2119 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(namedCtxt);
2120 if (nsdecl != 0 && !nsdecl->isAnonymousNamespace()) {
2122 clsname.erase (0, nsname.size() + 2);
2134 const clang::DeclContext *ctxt = cl.getDeclContext();
2135 while(ctxt && !ctxt->isNamespace()) {
2136 ctxt = ctxt->getParent();
2150 int closing_brackets = 0;
2154 if (ctxt && ctxt->isNamespace()) {
2159 const clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(ctxt);
2162 out <<
"namespace " << ns->getNameAsString() <<
" {" << std::endl;
2166 return closing_brackets;
2180 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2181 if (kind == clang::TSK_Undeclared ) {
2184 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2198 const char *name = which;
2199 const char *proto =
"size_t";
2200 const char *protoPlacement =
"size_t,void*";
2203 const clang::FunctionDecl *operatornew
2205 name, proto, interp,
2206 cling::LookupHelper::NoDiagnostics);
2207 const clang::FunctionDecl *operatornewPlacement
2209 name, protoPlacement, interp,
2210 cling::LookupHelper::NoDiagnostics);
2212 const clang::DeclContext *ctxtnew = 0;
2213 const clang::DeclContext *ctxtnewPlacement = 0;
2216 ctxtnew = operatornew->getParent();
2218 if (operatornewPlacement) {
2219 ctxtnewPlacement = operatornewPlacement->getParent();
2225 operatornewPlacement
2230 ctxtnew = operatornew->getParent();
2232 if (operatornewPlacement) {
2233 ctxtnewPlacement = operatornewPlacement->getParent();
2236 if (ctxtnewPlacement == 0) {
2244 if (ctxtnew == ctxtnewPlacement) {
2248 const clang::CXXRecordDecl* clnew = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnew);
2249 const clang::CXXRecordDecl* clnewPlacement = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnewPlacement);
2250 if (clnew == 0 && clnewPlacement == 0) {
2256 if (clnew != 0 && clnewPlacement == 0) {
2260 if (clnew == 0 && clnewPlacement != 0) {
2265 if (clnew->isDerivedFrom(clnewPlacement)) {
2295 const clang::CXXRecordDecl *decl,
2296 const cling::Interpreter &interp,
2302 std::string mappedname;
2320 classname.insert(0,
"::");
2323 finalString <<
"namespace ROOT {" <<
"\n";
2328 finalString <<
" // Wrappers around operator new" <<
"\n";
2329 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2331 finalString <<
"new(p) ";
2332 finalString << classname.c_str();
2333 finalString << args;
2334 finalString <<
" : ";
2336 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2337 finalString << classname.c_str();
2338 finalString << args;
2339 finalString <<
" : ";
2341 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2342 finalString <<
" }" <<
"\n";
2346 finalString <<
" static void *newArray_";
2347 finalString << mappedname.c_str();
2348 finalString <<
"(Long_t nElements, void *p) {";
2349 finalString <<
"\n";
2350 finalString <<
" return p ? ";
2352 finalString <<
"new(p) ";
2353 finalString << classname.c_str();
2354 finalString <<
"[nElements] : ";
2356 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2357 finalString << classname.c_str();
2358 finalString <<
"[nElements] : ";
2360 finalString <<
"new ";
2361 finalString << classname.c_str();
2362 finalString <<
"[nElements];";
2363 finalString <<
"\n";
2364 finalString <<
" }";
2365 finalString <<
"\n";
2370 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";
2374 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";
2378 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";
2382 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";
2386 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";
2388 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";
2392 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";
2394 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2401 const cling::Interpreter &interp,
2408 if (version == 0)
return;
2412 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2413 if (clxx == 0)
return;
2416 for(clang::CXXRecordDecl::base_class_const_iterator
iter = clxx->bases_begin(), end = clxx->bases_end();
2422 Internal::RStl::Instance().GenerateTClassFor(
iter->getType(), interp, normCtxt);
2427 for(clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
2431 std::string mTypename;
2437 if (!strcmp(shortTypeName,
"string")) {
2449 Internal::RStl::Instance().GenerateTClassFor(utype, interp, normCtxt);
2459 const clang::Type *rawtype = m.getType()->getCanonicalTypeInternal().getTypePtr();
2460 if (rawtype->isArrayType()) {
2461 rawtype = rawtype->getBaseElementTypeUnsafe ();
2475 const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2483 if (!funcCV)
return -1;
2485 if (funcCV == (clang::FunctionDecl*)-1)
return 1;
2487 const clang::CompoundStmt* FuncBody
2488 = llvm::dyn_cast_or_null<clang::CompoundStmt>(funcCV->getBody());
2489 if (!FuncBody)
return -1;
2490 if (FuncBody->size() != 1) {
2496 const clang::ReturnStmt* RetStmt
2497 = llvm::dyn_cast<clang::ReturnStmt>(FuncBody->body_back());
2498 if (!RetStmt)
return -1;
2499 const clang::Expr* RetExpr = RetStmt->getRetValue();
2505 llvm::APSInt RetRes;
2506 if (!RetExpr->isIntegerConstantExpr(RetRes, funcCV->getASTContext()))
2508 if (RetRes.isSigned()) {
2509 return (
Version_t)RetRes.getSExtValue();
2512 return (
Version_t)RetRes.getZExtValue();
2528 clang::QualType type = m.getType();
2540 clang::QualType type = base.getType();
2555 static char t[4096];
2556 static const char* constwd =
"const ";
2557 static const char* constwdend =
"const";
2562 for (s=typeDesc;*s;s++) {
2565 if (lev==0 && *s==
'*')
continue;
2566 if (lev==0 && (strncmp(constwd,s,strlen(constwd))==0
2567 ||strcmp(constwdend,s)==0 ) ) {
2568 s+=strlen(constwd)-1;
2571 if (lev==0 && *s==
' ' && *(s+1)!=
'*') { p =
t;
continue;}
2572 if (p - t > (
long)
sizeof(t)) {
2573 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2586 const cling::Interpreter& interp)
2591 if (comment[0] ==
'!')
return false;
2593 clang::QualType type = m.getType();
2595 if (type->isReferenceType()) {
2600 std::string mTypeName = type.getAsString(m.getASTContext().getPrintingPolicy());
2601 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2604 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2612 const clang::Type *rawtype = type.getTypePtr()->getBaseElementTypeUnsafe ();
2614 if (rawtype->isPointerType()) {
2616 clang::QualType pointee;
2617 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2619 rawtype = pointee.getTypePtr();
2623 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2628 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2632 if (version > 0)
return true;
2645 const clang::Type *rawtype = m.getType().getTypePtr();
2648 clang::QualType pointee;
2649 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2651 rawtype = pointee.getTypePtr();
2665 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2669 return rawtype->getAsCXXRecordDecl();
2678 const cling::Interpreter &interp,
2680 std::ostream& dictStream,
2682 bool isGenreflex=
false)
2684 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2686 if (!decl || !decl->isCompleteDefinition()) {
2690 std::string fullname;
2693 Internal::RStl::Instance().GenerateTClassFor(cl.
GetNormalizedName(), llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl()), interp, normCtxt);
2700 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2702 ROOT::TMetaUtils::Info(0,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2715 if (level < ROOT::TMetaUtils::gErrorIgnoreLevel)
2718 const char *type = 0;
2733 if (!location || !location[0]) {
2734 if (prefix) fprintf(stderr,
"%s: ", type);
2735 vfprintf(stderr, (
const char*)
va_(fmt), ap);
2737 if (prefix) fprintf(stderr,
"%s in <%s>: ", type, location);
2738 else fprintf(stderr,
"In <%s>: ", location);
2739 vfprintf(stderr, (
const char*)
va_(fmt), ap);
2746 gNumberOfWarningsAndErrors++;
2757 va_start(ap,
va_(fmt));
2768 va_start(ap,
va_(fmt));
2779 va_start(ap,
va_(fmt));
2790 va_start(ap,
va_(fmt));
2801 va_start(ap,
va_(fmt));
2818 const cling::Interpreter &interpreter,
2821 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2823 clang::QualType originalType = instanceType;
2827 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2829 clang::Qualifiers quals = instanceType.getQualifiers();
2830 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2831 if (newPointee != instanceType->getPointeeType()) {
2832 instanceType = Ctx.getPointerType(newPointee);
2834 instanceType = Ctx.getQualifiedType(instanceType, quals);
2836 return instanceType;
2841 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2843 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2844 clang::Qualifiers quals = instanceType.getQualifiers();
2845 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2847 if (newPointee != instanceType->getPointeeType()) {
2850 instanceType = Ctx.getLValueReferenceType(newPointee);
2852 instanceType = Ctx.getRValueReferenceType(newPointee);
2854 instanceType = Ctx.getQualifiedType(instanceType, quals);
2856 return instanceType;
2860 bool prefix_changed =
false;
2861 clang::NestedNameSpecifier* prefix = 0;
2862 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2863 const clang::ElaboratedType* etype
2864 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2867 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2868 prefix_changed = prefix != etype->getQualifier();
2869 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2875 const clang::TemplateSpecializationType* TST
2876 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2878 const clang::ClassTemplateSpecializationDecl* TSTdecl
2879 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2891 bool mightHaveChanged =
false;
2892 if (TST && TSTdecl) {
2894 clang::Sema&
S = interpreter.getCI()->getSema();
2895 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2896 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2897 clang::TemplateParameterList::iterator Param = Params->begin();
2901 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2903 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2904 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2905 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2906 for(clang::TemplateSpecializationType::iterator
2907 I = TST->begin(),
E = TST->end();
2909 I!=
E ? ++
I : 0, ++Idecl, ++Param) {
2913 if (
I->getKind() == clang::TemplateArgument::Template) {
2914 clang::TemplateName templateName =
I->getAsTemplate();
2915 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2917 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2919 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2920 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2921 clang::NestedNameSpecifier* nns;
2923 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx, ns);
2924 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2925 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2928 desArgs.push_back(*
I);
2931 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, templateDecl) );
2932 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2933 mightHaveChanged =
true;
2940 desArgs.push_back(*
I);
2944 clang::QualType SubTy =
I->getAsType();
2953 if (SubTy != newSubTy) {
2954 mightHaveChanged =
true;
2955 desArgs.push_back(clang::TemplateArgument(newSubTy));
2957 desArgs.push_back(*
I);
2960 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
2962 mightHaveChanged =
true;
2964 const clang::TemplateArgument& templateArg
2965 = TSTdecl->getTemplateArgs().get(Idecl);
2967 desArgs.push_back(templateArg);
2970 clang::QualType SubTy = templateArg.getAsType();
2972 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
2973 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
2975 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
2978 cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interpreter));
2979 clang::sema::HackForDefaultTemplateArg raii;
2980 bool HasDefaultArgs;
2981 clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
2990 if (ArgType.getArgument().isNull()
2993 "Template parameter substitution failed for %s around %s",
2994 instanceType.getAsString().c_str(),
2995 SubTy.getAsString().c_str()
2999 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
3000 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
3003 desArgs.push_back(clang::TemplateArgument(SubTy));
3012 if (mightHaveChanged) {
3013 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
3016 TST->getCanonicalTypeInternal());
3020 if (!prefix_changed && !mightHaveChanged)
return originalType;
3022 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
3023 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
3025 return instanceType;
3045 llvm::StringRef
title;
3048 if (clang::AnnotateAttr *
A = m.getAttr<clang::AnnotateAttr>())
3049 title =
A->getAnnotation();
3061 if (errnum) *errnum =
VALID;
3063 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3064 size_t rightbracket = title.find(
']');
3065 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3067 std::string working;
3068 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
3075 size_t indexvarlen = indexvar.size();
3076 for ( i=0; i<indexvarlen; i++) {
3077 if (!isspace(indexvar[i])) {
3078 working += indexvar[i];
3083 const char *tokenlist =
"*+-";
3084 char *
current =
const_cast<char*
>(working.c_str());
3085 current = strtok(current,tokenlist);
3087 while (current!=0) {
3089 if (isdigit(current[0])) {
3090 for(i=0;i<strlen(current);i++) {
3091 if (!isdigit(current[0])) {
3096 if (errstr) *errstr =
current;
3097 if (errnum) *errnum =
NOT_INT;
3098 return llvm::StringRef();
3104 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(m.getDeclContext());
3105 const clang::FieldDecl *index1 = 0;
3107 index1 = GetDataMemberFromAll(*parent_clxx, current );
3109 if ( IsFieldDeclInt(index1) ) {
3115 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3119 if ( field_iter->getNameAsString() == m.getNameAsString() ) {
3125 if (errstr) *errstr =
current;
3126 if (errnum) *errnum =
NOT_DEF;
3127 return llvm::StringRef();
3129 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3137 if (errstr) *errstr =
current;
3138 if (errnum) *errnum =
NOT_INT;
3139 return llvm::StringRef();
3144 index1 = GetDataMemberFromAllParents( *parent_clxx, current );
3146 if ( IsFieldDeclInt(index1) ) {
3153 if (errnum) *errnum =
NOT_INT;
3154 if (errstr) *errstr =
current;
3158 if (errnum) *errnum =
NOT_INT;
3159 if (errstr) *errstr =
current;
3160 return llvm::StringRef();
3162 if ( found && (index1->getAccess() == clang::AS_private) ) {
3165 if (errstr) *errstr =
current;
3167 return llvm::StringRef();
3174 if (errstr) *errstr = indexvar;
3175 if (errnum) *errnum =
UNKNOWN;
3176 return llvm::StringRef();
3181 current = strtok(0,tokenlist);
3194 out.resize(strlen(in)*2);
3195 unsigned int i=0,j=0,
c;
3197 if (out.capacity() < (j+3)) {
3201 case '+': strcpy(const_cast<char*>(out.data())+j,
"pL"); j+=2;
break;
3202 case '-': strcpy(const_cast<char*>(out.data())+j,
"mI"); j+=2;
break;
3203 case '*': strcpy(const_cast<char*>(out.data())+j,
"mU"); j+=2;
break;
3204 case '/': strcpy(const_cast<char*>(out.data())+j,
"dI"); j+=2;
break;
3205 case '&': strcpy(const_cast<char*>(out.data())+j,
"aN"); j+=2;
break;
3206 case '%': strcpy(const_cast<char*>(out.data())+j,
"pE"); j+=2;
break;
3207 case '|': strcpy(const_cast<char*>(out.data())+j,
"oR"); j+=2;
break;
3208 case '^': strcpy(const_cast<char*>(out.data())+j,
"hA"); j+=2;
break;
3209 case '>': strcpy(const_cast<char*>(out.data())+j,
"gR"); j+=2;
break;
3210 case '<': strcpy(const_cast<char*>(out.data())+j,
"lE"); j+=2;
break;
3211 case '=': strcpy(const_cast<char*>(out.data())+j,
"eQ"); j+=2;
break;
3212 case '~': strcpy(const_cast<char*>(out.data())+j,
"wA"); j+=2;
break;
3213 case '.': strcpy(const_cast<char*>(out.data())+j,
"dO"); j+=2;
break;
3214 case '(': strcpy(const_cast<char*>(out.data())+j,
"oP"); j+=2;
break;
3215 case ')': strcpy(const_cast<char*>(out.data())+j,
"cP"); j+=2;
break;
3216 case '[': strcpy(const_cast<char*>(out.data())+j,
"oB"); j+=2;
break;
3217 case ']': strcpy(const_cast<char*>(out.data())+j,
"cB"); j+=2;
break;
3218 case '!': strcpy(const_cast<char*>(out.data())+j,
"nO"); j+=2;
break;
3219 case ',': strcpy(const_cast<char*>(out.data())+j,
"cO"); j+=2;
break;
3220 case '$': strcpy(const_cast<char*>(out.data())+j,
"dA"); j+=2;
break;
3221 case ' ': strcpy(const_cast<char*>(out.data())+j,
"sP"); j+=2;
break;
3222 case ':': strcpy(const_cast<char*>(out.data())+j,
"cL"); j+=2;
break;
3223 case '"': strcpy(const_cast<char*>(out.data())+j,
"dQ"); j+=2;
break;
3224 case '@': strcpy(const_cast<char*>(out.data())+j,
"aT"); j+=2;
break;
3225 case '\'': strcpy(const_cast<char*>(out.data())+j,
"sQ"); j+=2;
break;
3226 case '\\': strcpy(const_cast<char*>(out.data())+j,
"fI"); j+=2;
break;
3227 default: out[j++]=
c;
break;
3234 std::size_t firstNonNumber = out.find_first_not_of(
"0123456789");
3235 out.replace(0,firstNonNumber,
"");
3240 static clang::SourceLocation
3242 clang::SourceLocation sourceLoc) {
3244 if (!sourceLoc.isFileID()) {
3245 return sourceManager.getExpansionRange(sourceLoc).second;
3254 const cling::Interpreter& interp)
3284 using namespace clang;
3285 SourceLocation headerLoc = decl.getLocation();
3287 static const char invalidFilename[] =
"invalid";
3288 if (!headerLoc.isValid())
return invalidFilename;
3290 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3292 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3294 FileID headerFID = sourceManager.getFileID(headerLoc);
3295 SourceLocation includeLoc
3297 sourceManager.getIncludeLoc(headerFID));
3299 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3300 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3301 const DirectoryLookup *foundDir = 0;
3304 const FileEntry *FEhdr
3308 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3313 headerFID = sourceManager.getFileID(includeLoc);
3314 headerFE = sourceManager.getFileEntryForID(headerFID);
3316 sourceManager.getIncludeLoc(headerFID));
3319 if (!headerFE)
return invalidFilename;
3320 llvm::StringRef headerFileName = headerFE->getName();
3331 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3332 const FileEntry* FELong = 0;
3334 for (llvm::sys::path::const_iterator
3335 IDir = llvm::sys::path::begin(headerFileName),
3336 EDir = llvm::sys::path::end(headerFileName);
3337 !FELong && IDir != EDir; ++IDir) {
3343 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3344 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3345 assert(trailingPart.data() + trailingPart.size()
3346 == headerFileName.data() + headerFileName.size()
3347 &&
"Mismatched partitioning of file name!");
3348 const DirectoryLookup* FoundDir = 0;
3349 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3351 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3358 return invalidFilename;
3362 for (llvm::sys::path::reverse_iterator
3363 IDir = llvm::sys::path::rbegin(headerFileName),
3364 EDir = llvm::sys::path::rend(headerFileName);
3365 IDir != EDir; ++IDir) {
3366 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3367 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3368 assert(trailingPart.data() + trailingPart.size()
3369 == headerFileName.data() + headerFileName.size()
3370 &&
"Mismatched partitioning of file name!");
3371 const DirectoryLookup* FoundDir = 0;
3374 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3376 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3379 return trailingPart;
3383 return invalidFilename;
3389 const clang::QualType &qtype,
3390 const clang::ASTContext &astContext)
3392 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3401 const clang::QualType &qtype,
3402 const cling::Interpreter &interpreter)
3406 interpreter.getCI()->getASTContext());
3418 const char* rootsys = getenv(
"ROOTSYS");
3420 Error(0,
"Environment variable ROOTSYS not set!");
3423 return std::string(
"-I") + rootsys +
"/etc";
3426 return std::string(
"-I") + ROOTETCDIR;
3435 #ifdef R__EXTERN_LLVMDIR
3436 return R__EXTERN_LLVMDIR;
3439 .substr(2, std::string::npos) +
"/cling";
3448 clang::ClassTemplateDecl*& ctd,
3449 clang::ClassTemplateSpecializationDecl*& ctsd)
3451 using namespace clang;
3452 const Type* theType = qt.getTypePtr();
3459 if (theType->isPointerType()) {
3463 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3464 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3466 ctd = ctsd->getSpecializedTemplate();
3471 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3476 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3478 ctd = ctsd->getSpecializedTemplate();
3493 using namespace clang;
3494 ClassTemplateSpecializationDecl* ctsd;
3495 ClassTemplateDecl* ctd;
3509 using namespace clang;
3510 TemplateName theTemplateName;
3512 const Type* theType = qt.getTypePtr();
3514 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3515 theTemplateName = tst->getTemplateName();
3518 theTemplateName = TemplateName(ctd);
3521 return theTemplateName;
3527 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3528 const clang::NamedDecl& tPar,
3529 const cling::Interpreter& interp,
3532 using namespace ROOT::TMetaUtils;
3533 using namespace clang;
3536 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3537 if (!ttpdPtr)
return false;
3538 if (!ttpdPtr->hasDefaultArgument())
return false;
3541 QualType tParQualType = ttpdPtr->getDefaultArgument();
3542 const QualType tArgQualType = tArg.getAsType();
3549 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3560 const clang::ElaboratedType* etype
3561 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3563 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3564 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3567 const TemplateSpecializationType* tst =
3568 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3573 ClassTemplateSpecializationDecl* TSTdecl
3574 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3579 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3582 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3585 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3590 TemplateArgument newArg = tArg;
3592 clang::Sema&
S = interp.getCI()->getSema();
3593 cling::Interpreter::PushTransactionRAII clingRAII(const_cast<cling::Interpreter*>(&interp));
3594 clang::sema::HackForDefaultTemplateArg raii;
3595 bool HasDefaultArgs;
3596 TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
3604 newArg = defTArgLoc.getArgument();
3605 if (newArg.isNull() ||
3608 "Template parameter substitution failed!");
3611 ClassTemplateSpecializationDecl* nTSTdecl
3612 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3615 isEqual = nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl() ||
3616 tParQualType.getTypePtr() == newArg.getAsType().getTypePtr();
3628 const clang::NamedDecl& tPar)
3630 using namespace clang;
3631 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3632 if (!nttpdPtr)
return false;
3633 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3635 if (!nttpd.hasDefaultArgument())
3639 llvm::APSInt defaultValueAPSInt(64,
false);
3640 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3641 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3642 defArgExpr->isIntegerConstantExpr(defaultValueAPSInt, astCtxt);
3645 const int value = tArg.getAsIntegral().getLimitedValue();
3648 return value == defaultValueAPSInt;
3658 using namespace clang;
3659 if (!nDecl)
return false;
3660 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3661 return ttpd->hasDefaultArgument();
3662 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3663 return nttpd->hasDefaultArgument();
3673 const clang::QualType& vanillaType,
3674 const cling::Interpreter& interp,
3677 using namespace ROOT::TMetaUtils;
3678 using namespace clang;
3682 ClassTemplateSpecializationDecl* ctsd;
3683 ClassTemplateDecl* ctd;
3690 QualType originalNormalizedType = normalizedType;
3692 const ASTContext& astCtxt = ctsd->getASTContext();
3697 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3699 clang::Qualifiers quals = normalizedType.getQualifiers();
3700 auto valNormalizedType = normalizedType->getPointeeType();
3701 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3702 normalizedType = astCtxt.getPointerType(valNormalizedType);
3704 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3710 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3712 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3713 clang::Qualifiers quals = normalizedType.getQualifiers();
3714 auto valNormType = normalizedType->getPointeeType();
3715 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3719 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3721 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3723 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3728 bool prefix_changed =
false;
3729 clang::NestedNameSpecifier* prefix =
nullptr;
3730 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3731 const clang::ElaboratedType* etype
3732 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3736 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3737 prefix_changed = prefix != etype->getQualifier();
3738 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3744 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3745 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3746 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3747 if (tpl->getMinRequiredArguments () < tpl->size())
3748 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3750 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3751 const TemplateParameterList& tPars = *tParsPtr;
3752 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3756 if (theTemplateName.isNull()) {
3757 normalizedType=originalNormalizedType;
3761 const TemplateSpecializationType* normalizedTst =
3762 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3763 if (!normalizedTst) {
3764 normalizedType=originalNormalizedType;
3768 const clang::ClassTemplateSpecializationDecl* TSTdecl
3769 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3777 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3779 const int nArgs = tArgs.size();
3780 const int nNormArgs = normalizedTst->getNumArgs();
3782 bool mightHaveChanged =
false;
3785 for (
int index = 0; index != nArgs; ++index) {
3786 const NamedDecl* tParPtr = tPars.getParam(index);
3787 if (!tParPtr)
Error(
"KeepNParams",
3788 "The parameter number %s is null.\n",
3791 const TemplateArgument& tArg = tArgs.get(index);
3795 if (index == nNormArgs)
break;
3797 TemplateArgument NormTArg(normalizedTst->getArgs()[index]);
3800 if (isStdDropDefault) shouldKeepArg =
false;
3812 QualType thisNormQualType = NormTArg.getAsType();
3813 QualType thisArgQualType = tArg.getAsType();
3818 mightHaveChanged |= (thisNormQualType != thisArgQualType);
3819 NormTArg = TemplateArgument(thisNormQualType);
3821 argsToKeep.push_back(NormTArg);
3824 if (!isStdDropDefault) {
3826 mightHaveChanged =
true;
3836 auto argKind = tArg.getKind();
3839 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3840 }
else if (argKind == clang::TemplateArgument::Integral){
3844 argsToKeep.push_back(NormTArg);
3846 mightHaveChanged =
true;
3852 if (!prefix_changed && !mightHaveChanged) {
3853 normalizedType = originalNormalizedType;
3858 if (mightHaveChanged) {
3859 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3860 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3863 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3864 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3870 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3871 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3885 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3887 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt, type, normCtxt.
GetConfig(),
true );
3893 KeepNParams(normalizedType,type,interpreter,normCtxt);
3895 return normalizedType;
3909 if (type.isNull()) {
3916 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3917 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
3918 policy.SuppressTagKeyword =
true;
3919 policy.SuppressScope =
true;
3920 policy.AnonymousTagLocations =
false;
3925 std::string normalizedNameStep1;
3926 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
3936 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
3937 norm_name.erase(0,2);
3945 const clang::TypeDecl* typeDecl,
3946 const cling::Interpreter &interpreter)
3949 const clang::Sema &sema = interpreter.getSema();
3950 clang::ASTContext& astCtxt = sema.getASTContext();
3951 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
3963 const std::string defaultInclude (
"include");
3966 const char* rootSysContent = getenv(
"ROOTSYS");
3967 if (rootSysContent) {
3968 std::string incl_rootsys (rootSysContent);
3969 return incl_rootsys +
"/" + defaultInclude;
3971 Error(0,
"Environment variable ROOTSYS not set");
3972 return defaultInclude;
3979 return defaultInclude;
3987 std::string dictFileName(moduleName);
3988 dictFileName +=
"_rdict.pcm";
3989 return dictFileName;
3996 const char* moduleFileName,
3997 const char* headers[])
3999 clang::Preprocessor& PP = CI->getPreprocessor();
4000 clang::ModuleMap& ModuleMap = PP.getHeaderSearchInfo().getModuleMap();
4003 clang::HeaderSearch& HS = CI->getPreprocessor().getHeaderSearchInfo();
4004 HS.setModuleCachePath(llvm::sys::path::parent_path(moduleFileName));
4007 moduleName = llvm::sys::path::stem(moduleName);
4009 std::pair<clang::Module*, bool> modCreation;
4012 = ModuleMap.findOrCreateModule(moduleName.str(),
4015 if (!modCreation.second && !strstr(moduleFileName,
"/allDict_rdict.pcm")) {
4016 std::cerr <<
"TMetaUtils::declareModuleMap: "
4017 "Duplicate definition of dictionary module "
4018 << moduleFileName << std::endl;
4023 clang::HeaderSearch& HdrSearch = PP.getHeaderSearchInfo();
4024 for (
const char** hdr = headers; hdr && *hdr; ++hdr) {
4025 const clang::DirectoryLookup* CurDir;
4026 const clang::FileEntry* hdrFileEntry
4027 = HdrSearch.LookupFile(*hdr, clang::SourceLocation(),
4029 llvm::ArrayRef<std::pair<
const clang::FileEntry *,
4030 const clang::DirectoryEntry *>>(),
4034 if (!hdrFileEntry) {
4035 std::cerr <<
"TMetaUtils::declareModuleMap: "
4036 "Cannot find header file " << *hdr
4037 <<
" included in dictionary module "
4039 <<
" in include search path!";
4040 hdrFileEntry = PP.getFileManager().getFile(*hdr,
false,
4042 }
else if (getenv(
"ROOT_MODULES")) {
4044 llvm::StringRef srHdrDir(hdrFileEntry->getName());
4045 srHdrDir = llvm::sys::path::parent_path(srHdrDir);
4046 const clang::DirectoryEntry* Dir
4047 = PP.getFileManager().getDirectory(srHdrDir);
4049 HdrSearch.setDirectoryHasModuleMap(Dir);
4053 ModuleMap.addHeader(modCreation.first,
4054 clang::Module::Header{*hdr,hdrFileEntry},
4055 clang::ModuleMap::NormalHeader);
4057 return modCreation.first;
4061 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4087 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4088 clang::SourceLocation sourceLocation = decl.getLocEnd();
4091 sourceLocation = sourceManager.getExpansionRange(sourceLocation).second;
4092 if (sourceManager.isLoadedSourceLocation(sourceLocation)) {
4098 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4102 bool skipToSemi =
true;
4103 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4104 if (FD->isImplicit()) {
4108 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4112 }
else if (FD->doesThisDeclarationHaveABody()) {
4115 assert((decl.getLocEnd() != sourceLocation || *commentStart ==
'}'
4117 &&
"Expected macro or end of body at '}'");
4118 if (*commentStart) ++commentStart;
4121 while (*commentStart && isspace(*commentStart)
4122 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4125 if (*commentStart ==
';') ++commentStart;
4129 }
else if (
const clang::EnumConstantDecl* ECD
4130 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4132 if (ECD->getNextDeclInContext())
4133 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4141 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4143 if (*commentStart ==
';') ++commentStart;
4147 while ( *commentStart && isspace(*commentStart)
4148 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4152 if (commentStart[0] !=
'/' ||
4153 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4163 unsigned int skipChars = 2;
4164 if (commentStart[0] ==
'/' &&
4165 commentStart[1] ==
'/' &&
4166 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4167 commentStart[3] ==
'<') {
4169 }
else if (commentStart[0] ==
'/' &&
4170 commentStart[1] ==
'*' &&
4171 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4172 commentStart[3] ==
'<') {
4176 commentStart += skipChars;
4179 while ( *commentStart && isspace(*commentStart)
4180 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4183 const char* commentEnd = commentStart;
4185 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4191 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4197 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4198 *loc = sourceLocation.getLocWithOffset(offset - 1);
4201 return llvm::StringRef(commentStart, commentEnd - commentStart);
4212 clang::SourceLocation *loc,
4213 const cling::Interpreter &interpreter)
4215 using namespace clang;
4216 SourceLocation commentSLoc;
4219 Sema& sema = interpreter.getCI()->getSema();
4221 const Decl* DeclFileLineDecl
4222 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4223 cling::LookupHelper::NoDiagnostics);
4224 if (!DeclFileLineDecl)
return llvm::StringRef();
4227 SourceLocation maybeMacroLoc = DeclFileLineDecl->getLocation();
4228 bool isClassDefMacro = maybeMacroLoc.isMacroID() && sema.findMacroSpelling(maybeMacroLoc,
"ClassDef");
4229 if (isClassDefMacro) {
4238 return llvm::StringRef();
4250 if (rawtype->isElaboratedTypeSpecifier() ) {
4251 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4253 if (rawtype->isArrayType()) {
4254 rawtype = type.getTypePtr()->getBaseElementTypeUnsafe ();
4256 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4258 clang::QualType pointee;
4259 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4261 rawtype = pointee.getTypePtr();
4263 if (rawtype->isElaboratedTypeSpecifier() ) {
4264 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4266 if (rawtype->isArrayType()) {
4267 rawtype = rawtype->getBaseElementTypeUnsafe ();
4271 if (rawtype->isArrayType()) {
4272 rawtype = rawtype->getBaseElementTypeUnsafe ();
4293 static const char *names[] =
4294 {
"shared_ptr",
"__shared_ptr",
4295 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4296 llvm::StringRef clname(cl.getName());
4297 for(
auto &&name : names) {
4298 if (clname == name)
return true;
4308 const clang::CXXRecordDecl ¤tCl)
4311 if (&cl == ¤tCl)
return true;
4313 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4316 if (
NULL == previous){
4335 const clang::CXXRecordDecl *thisDecl =
4336 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4340 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4345 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4378 using namespace clang;
4379 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4380 bool VisitTypedefType(
const TypedefType* TD) {
4383 bool VisitArrayType(
const ArrayType* AT) {
4384 return Visit(AT->getElementType().getTypePtr());
4386 bool VisitDecltypeType(
const DecltypeType* DT) {
4387 return Visit(DT->getUnderlyingType().getTypePtr());
4389 bool VisitPointerType(
const PointerType*
PT) {
4390 return Visit(PT->getPointeeType().getTypePtr());
4392 bool VisitReferenceType(
const ReferenceType* RT) {
4393 return Visit(RT->getPointeeType().getTypePtr());
4395 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4396 return Visit(STST->getReplacementType().getTypePtr());
4398 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4399 for (
int I = 0,
N = TST->getNumArgs();
I <
N; ++
I) {
4400 const TemplateArgument& TA = TST->getArg(
I);
4402 && Visit(TA.getAsType().getTypePtr()))
4407 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4410 bool VisitTypeOfType(
const TypeOfType* TOT) {
4411 return TOT->getUnderlyingType().getTypePtr();
4413 bool VisitElaboratedType(
const ElaboratedType* ET) {
4414 NestedNameSpecifier* NNS = ET->getQualifier();
4416 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4417 if (Visit(NNS->getAsType()))
4420 NNS = NNS->getPrefix();
4422 return Visit(ET->getNamedType().getTypePtr());
4437 if (!instance)
return input;
4443 using namespace llvm;
4444 using namespace clang;
4445 const clang::ASTContext &Ctxt = instance->getAsCXXRecordDecl()->getASTContext();
4448 const clang::ElaboratedType* etype
4449 = llvm::dyn_cast<clang::ElaboratedType>(input.getTypePtr());
4453 clang::Qualifiers scope_qualifiers = input.getLocalQualifiers();
4454 assert(instance->getAsCXXRecordDecl()!=0 &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4456 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),instance);
4457 clang::QualType subTy =
ReSubstTemplateArg(clang::QualType(etype->getNamedType().getTypePtr(),0),instance);
4459 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4460 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4464 QualType QT = input;
4468 if (isa<clang::PointerType>(QT.getTypePtr())) {
4470 Qualifiers quals = QT.getQualifiers();
4473 if (nQT == QT->getPointeeType())
return QT;
4475 QT = Ctxt.getPointerType(nQT);
4477 QT = Ctxt.getQualifiedType(QT, quals);
4483 if (isa<ReferenceType>(QT.getTypePtr())) {
4485 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4486 Qualifiers quals = QT.getQualifiers();
4489 if (nQT == QT->getPointeeType())
return QT;
4493 QT = Ctxt.getLValueReferenceType(nQT);
4495 QT = Ctxt.getRValueReferenceType(nQT);
4497 QT = Ctxt.getQualifiedType(QT, quals);
4503 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4505 Qualifiers quals = QT.getQualifiers();
4507 if (isa<ConstantArrayType>(QT.getTypePtr())) {
4508 const ConstantArrayType *arr = dyn_cast<ConstantArrayType>(QT.getTypePtr());
4512 if (newQT == arr->getElementType())
return QT;
4513 QT = Ctxt.getConstantArrayType (newQT,
4515 arr->getSizeModifier(),
4516 arr->getIndexTypeCVRQualifiers());
4518 }
else if (isa<DependentSizedArrayType>(QT.getTypePtr())) {
4519 const DependentSizedArrayType *arr = dyn_cast<DependentSizedArrayType>(QT.getTypePtr());
4523 if (newQT == QT)
return QT;
4524 QT = Ctxt.getDependentSizedArrayType (newQT,
4526 arr->getSizeModifier(),
4527 arr->getIndexTypeCVRQualifiers(),
4528 arr->getBracketsRange());
4530 }
else if (isa<IncompleteArrayType>(QT.getTypePtr())) {
4531 const IncompleteArrayType *arr
4532 = dyn_cast<IncompleteArrayType>(QT.getTypePtr());
4536 if (newQT == arr->getElementType())
return QT;
4537 QT = Ctxt.getIncompleteArrayType (newQT,
4538 arr->getSizeModifier(),
4539 arr->getIndexTypeCVRQualifiers());
4541 }
else if (isa<VariableArrayType>(QT.getTypePtr())) {
4542 const VariableArrayType *arr
4543 = dyn_cast<VariableArrayType>(QT.getTypePtr());
4547 if (newQT == arr->getElementType())
return QT;
4548 QT = Ctxt.getVariableArrayType (newQT,
4550 arr->getSizeModifier(),
4551 arr->getIndexTypeCVRQualifiers(),
4552 arr->getBracketsRange());
4556 QT = Ctxt.getQualifiedType(QT, quals);
4561 etype = llvm::dyn_cast<clang::ElaboratedType>(instance);
4563 instance = etype->getNamedType().getTypePtr();
4564 if (!instance)
return input;
4567 const clang::TemplateSpecializationType* TST
4568 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(instance);
4570 if (!TST)
return input;
4572 const clang::ClassTemplateSpecializationDecl* TSTdecl
4573 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instance->getAsCXXRecordDecl());
4575 const clang::SubstTemplateTypeParmType *substType
4576 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(input.getTypePtr());
4580 const clang::ClassTemplateDecl *replacedCtxt = 0;
4582 const clang::DeclContext *replacedDeclCtxt = substType->getReplacedParameter()->getDecl()->getDeclContext();
4583 const clang::CXXRecordDecl *decl = llvm::dyn_cast<clang::CXXRecordDecl>(replacedDeclCtxt);
4584 unsigned int index = substType->getReplacedParameter()->getIndex();
4587 if (decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4588 const clang::ClassTemplatePartialSpecializationDecl *spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(decl);
4590 unsigned int depth = substType->getReplacedParameter()->getDepth();
4592 const TemplateArgument *instanceArgs = spec->getTemplateArgs().data();
4593 unsigned int instanceNArgs = spec->getTemplateArgs().size();
4597 for(
unsigned int A = 0;
A < instanceNArgs; ++
A) {
4599 clang::QualType argQualType = instanceArgs[
A].getAsType();
4601 const clang::TemplateTypeParmType *replacementType;
4603 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(argQualType);
4605 if (!replacementType) {
4606 const clang::SubstTemplateTypeParmType *argType
4607 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(argQualType);
4609 clang::QualType replacementQT = argType->getReplacementType();
4610 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(replacementQT);
4613 if (replacementType &&
4614 depth == replacementType->getDepth() &&
4615 index == replacementType->getIndex() )
4622 replacedCtxt = spec->getSpecializedTemplate();
4624 replacedCtxt = decl->getDescribedClassTemplate();
4627 replacedCtxt = llvm::dyn_cast<clang::ClassTemplateDecl>(replacedDeclCtxt);
4630 if (replacedCtxt->getCanonicalDecl() == TSTdecl->getSpecializedTemplate()->getCanonicalDecl()
4632 substType->getReplacedParameter()->getDecl()
4633 == TSTdecl->getSpecializedTemplate ()->getTemplateParameters()->getParam(index))
4635 if ( index >= TST->getNumArgs() ) {
4642 return TST->getArg(index).getAsType();
4647 const clang::TemplateSpecializationType* inputTST
4648 = llvm::dyn_cast<
const clang::TemplateSpecializationType>(input.getTypePtr());
4649 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4652 bool mightHaveChanged =
false;
4653 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4654 for(clang::TemplateSpecializationType::iterator
I = inputTST->begin(),
E = inputTST->end();
4657 desArgs.push_back(*
I);
4661 clang::QualType SubTy =
I->getAsType();
4663 if (llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4664 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4666 mightHaveChanged = SubTy != newSubTy;
4667 if (!newSubTy.isNull()) {
4668 desArgs.push_back(clang::TemplateArgument(newSubTy));
4671 desArgs.push_back(*
I);
4675 if (mightHaveChanged) {
4676 clang::Qualifiers qualifiers = input.getLocalQualifiers();
4677 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4680 inputTST->getCanonicalTypeInternal());
4681 input = astCtxt.getQualifiedType(input, qualifiers);
4693 if ( nArgsToRemove == 0 || name ==
"")
4698 const unsigned int length = name.length();
4700 unsigned int nArgsRemoved=0;
4701 unsigned int nBraces=0;
4703 while (nArgsRemoved!=nArgsToRemove && cur<length){
4705 if (c ==
'<') nBraces++;
4706 if (c ==
'>') nBraces--;
4707 if (c ==
',' && nBraces==1 ) nArgsRemoved++;
4711 name = name.substr(0,cur)+
">";
4721 static const char *stls[] =
4722 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4723 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",0};
4736 for(
int k=1;stls[k];k++) {
if (type.equals(stls[k]))
return values[k];}
4747 TND = TND->getMostRecentDecl();
4748 while (TND && !(TND->hasAttrs()))
4749 TND = TND->getPreviousDecl();
4761 TD = TD->getMostRecentDecl();
4762 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4763 TD = TD->getPreviousDecl();
4772 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4774 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4775 if (!enclosingNamespaceDeclCtxt)
return;
4777 const clang::NamespaceDecl* enclosingNamespace =
4778 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4779 if (!enclosingNamespace)
return;
4781 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4782 enclosingNamespace->isInline()));
4792 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4794 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4797 if (!enclosingNamespaceDeclCtxt) {
4803 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4804 if (!enclosingNamespace)
return;
4807 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4808 enclosingNamespace->isInline()));
4819 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4821 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4822 if (!enclosingDeclCtxt)
return 0;
4824 unsigned int scopeType;
4826 if (
auto enclosingNamespacePtr =
4827 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4828 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4829 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4833 if (
auto enclosingClassPtr =
4834 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4835 return enclosingClassPtr;
4848 std::string::size_type beginVar = 0;
4849 std::string::size_type endVar = 0;
4850 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4851 && beginVar + 1 < txt.length()) {
4852 std::string::size_type beginVarName = beginVar + 1;
4853 std::string::size_type endVarName = std::string::npos;
4854 if (txt[beginVarName] ==
'(') {
4856 endVarName = txt.find(
')', beginVarName);
4858 if (endVarName == std::string::npos) {
4860 varname, txt.c_str() + beginVar);
4863 endVar = endVarName + 1;
4866 beginVarName = beginVar + 1;
4867 endVarName = beginVarName;
4868 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
4870 endVar = endVarName;
4873 const char* val = getenv(txt.substr(beginVarName,
4874 endVarName - beginVarName).c_str());
4877 txt.replace(beginVar, endVar - beginVar, val);
4878 int lenval = strlen(val);
4879 int delta = lenval - (endVar - beginVar);
4883 beginVar = endVar + 1;
4895 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
4899 std::istringstream envInclPathsStream(envInclPath);
4900 std::string inclPath;
4901 while (std::getline(envInclPathsStream, inclPath,
':')) {
4904 if (!inclPath.empty()) {
4905 clingArgs.push_back(
"-I");
4906 clingArgs.push_back(inclPath);
4917 size_t start_pos = 0;
4922 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
4923 str.replace(start_pos, from.length(), to);
4924 start_pos += to.length();
4925 if (recurse) changed =
true;
4938 static const std::string gPathSeparator (
"\\");
4940 static const std::string gPathSeparator (
"/");
4942 return gPathSeparator;
4949 if (theString.size() < theSubstring.size())
return false;
4950 const unsigned int theSubstringSize = theSubstring.size();
4951 return 0 == theString.compare(theString.size() - theSubstringSize,
4960 if (theString.size() < theSubstring.size())
return false;
4961 const unsigned int theSubstringSize = theSubstring.size();
4962 return 0 == theString.compare(0,
4971 const cling::Interpreter &interp)
4973 clang::Sema &sema = interp.getSema();
4974 cling::Transaction theTransaction(sema);
4975 std::set<clang::Decl *> addedDecls;
4976 for (
auto decl : decls) {
4978 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
4979 theTransaction.append(ncDecl);
4981 std::string newFwdDecl;
4982 llvm::raw_string_ostream llvmOstr(newFwdDecl);
4983 interp.forwardDeclare(theTransaction, sema, llvmOstr,
true,
nullptr);
4996 std::string& defString)
5008 std::string& defString)
5010 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5013 if (rcdPtr)
return rcdPtr;
5016 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5018 std::string scopeName;
5019 std::string scopeContent;
5020 unsigned int scopeIndex;
5021 for (
auto const & encScope : enclosingNamespaces){
5022 scopeIndex = encScope.second;
5023 scopeName = encScope.first;
5024 scopeContent =
" { " + defString +
" }";
5025 defString = scopeType[scopeIndex] +
5047 const clang::TemplateParameterList& tmplParamList,
5048 const cling::Interpreter& interpreter)
5050 static const char* paramPackWarning=
"Template parameter pack found: autoload of variadic templates is not supported yet.\n";
5053 for (
auto prmIt = tmplParamList.begin();
5054 prmIt != tmplParamList.end(); prmIt++){
5056 if (prmIt != tmplParamList.begin())
5057 templateArgs +=
", ";
5059 auto nDecl = *prmIt;
5060 std::string typeName;
5062 if(nDecl->isParameterPack ()){
5068 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5069 typeName =
"typename " + (*prmIt)->getNameAsString();
5072 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5073 auto theType = nttpd->getType();
5076 if (theType.getAsString().find(
"enum") != std::string::npos){
5077 std::string astDump;
5078 llvm::raw_string_ostream ostream(astDump);
5079 nttpd->dump(ostream);
5081 ROOT::TMetaUtils::Warning(0,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5090 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5093 std::string astDump;
5094 llvm::raw_string_ostream ostream(astDump);
5095 ttpd->dump(ostream);
5097 ROOT::TMetaUtils::Error(0,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5102 templateArgs += typeName;
5113 const cling::Interpreter& interpreter,
5114 std::string& defString)
5116 std::string templatePrefixString;
5117 auto tmplParamList= templDecl.getTemplateParameters();
5118 if (!tmplParamList){
5120 "Cannot extract template parameter list for %s",
5121 templDecl.getNameAsString().c_str());
5128 "Problems with arguments for forward declaration of class %s\n",
5129 templDecl.getNameAsString().c_str());
5132 templatePrefixString =
"template " + templatePrefixString +
" ";
5134 defString = templatePrefixString +
"class " + templDecl.getNameAsString();
5135 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5149 std::string& argFwdDecl,
5150 const cling::Interpreter& interpreter,
5151 bool acceptStl=
false)
5153 using namespace ROOT::TMetaUtils::AST2SourceTools;
5159 auto argQualType = arg.getAsType();
5162 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5164 auto argTypePtr = argQualType.getTypePtr();
5167 if (llvm::isa<clang::EnumType>(argTypePtr)){
5172 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5177 if (llvm::isa<clang::TypedefType>(argTypePtr)){
5178 auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr);
5183 if (llvm::isa<clang::RecordType>(argQualType)){
5185 auto argRecTypePtr = llvm::cast<clang::RecordType>(argTypePtr);
5186 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5201 const cling::Interpreter& interpreter,
5202 std::string& defString,
5210 if (!recordDecl.getIdentifier())
5214 std::string argsFwdDecl;
5216 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5217 std::string argFwdDecl;
5219 std::cout <<
"Class " << recordDecl.getNameAsString()
5220 <<
" is a template specialisation. Treating its arguments.\n";
5221 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5224 std::cout <<
" o Template argument ";
5226 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5228 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5235 argsFwdDecl+=argFwdDecl;
5239 defString=argsFwdDecl;
5244 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5247 defString = argsFwdDecl +
"\n" + defString;
5252 defString =
"class " + recordDecl.getNameAsString() +
";";
5253 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5261 defString = argsFwdDecl +
"\n" + defString;
5272 const cling::Interpreter& interpreter,
5273 std::string& fwdDeclString,
5274 std::unordered_set<std::string>* fwdDeclSetPtr)
5276 std::string
buffer = tdnDecl.getNameAsString();
5277 std::string underlyingName;
5278 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5279 if (
const clang::TagType* TT
5280 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5281 if (clang::NamedDecl* ND = TT->getDecl()) {
5282 if (!ND->getIdentifier()) {
5296 if (underlyingName.find(
">::") != std::string::npos)
5299 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5311 auto& ctxt = tdnDecl.getASTContext();
5312 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5314 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5315 std::string tdnFwdDecl;
5316 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5321 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5322 fwdDeclString+=tdnFwdDecl;
5323 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5324 std::string classFwdDecl;
5326 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: "
5327 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5336 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5337 fwdDeclString+=classFwdDecl;
5352 std::string& valAsString,
5353 const clang::PrintingPolicy& ppolicy)
5355 auto defArgExprPtr = par.getDefaultArg();
5356 auto& ctxt = par.getASTContext();
5357 if(!defArgExprPtr->isEvaluatable(ctxt)){
5361 auto defArgType = par.getType();
5364 if (defArgType->isBooleanType()){
5366 defArgExprPtr->EvaluateAsBooleanCondition (result,ctxt);
5367 valAsString=std::to_string(result);
5372 if (defArgType->isIntegerType()){
5374 defArgExprPtr->EvaluateAsInt(result,ctxt);
5375 auto uintVal = *result.getRawData();
5376 if (result.isNegative()){
5377 long long int intVal=uintVal*-1;
5378 valAsString=std::to_string(intVal);
5380 valAsString=std::to_string(uintVal);
5387 llvm::raw_string_ostream rso(valAsString);
5388 defArgExprPtr->printPretty(rso,
nullptr,ppolicy);
5389 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...
ClassImp(TAlienJobStatusList) void TAlienJobStatusList TString split(jobstatus->GetKey("split"))
Print information about jobs.
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.
std::vector< double > values
static const char * filename()
std::map< std::string, ROOT::Internal::TSchemaType > MembersTypeMap_t
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
std::map< std::string, std::string >::const_iterator iter
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'.
void Error(const char *location, const char *msgfmt,...)
SchemaRuleClassMap_t gReadRules
Double_t length(const TVector2 &v)
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
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 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
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members)
Check if given rule contains references to valid data members.
#define dest(otri, vertexptr)