24#include <unordered_set>
26#include "RConfigure.h"
34#include "clang/AST/ASTContext.h"
35#include "clang/AST/Attr.h"
36#include "clang/AST/CXXInheritance.h"
37#include "clang/AST/Decl.h"
38#include "clang/AST/DeclTemplate.h"
39#include "clang/AST/Mangle.h"
40#include "clang/AST/Type.h"
41#include "clang/AST/TypeVisitor.h"
42#include "clang/Frontend/CompilerInstance.h"
43#include "clang/Lex/HeaderSearch.h"
44#include "clang/Lex/ModuleMap.h"
45#include "clang/Lex/Preprocessor.h"
46#include "clang/Lex/PreprocessorOptions.h"
48#include "clang/Sema/Lookup.h"
49#include "clang/Sema/Sema.h"
50#include "clang/Sema/SemaDiagnostic.h"
52#include "cling/Interpreter/LookupHelper.h"
53#include "cling/Interpreter/Transaction.h"
54#include "cling/Interpreter/Interpreter.h"
55#include "cling/Utils/AST.h"
57#include "llvm/Support/Path.h"
58#include "llvm/Support/FileSystem.h"
61#include "../../../interpreter/llvm/src/tools/clang/lib/Sema/HackForDefaultTemplateArg.h"
66#define strncasecmp _strnicmp
77 llvm::SmallString<256> result_path;
78 llvm::sys::fs::real_path(path, result_path,
true);
79 return result_path.str().str();
86 using DeclsCont_t = TNormalizedCtxt::Config_t::SkipCollection;
103 bool replace =
false);
113static clang::NestedNameSpecifier *AddDefaultParametersNNS(
const clang::ASTContext& Ctx,
114 clang::NestedNameSpecifier* scope,
115 const cling::Interpreter &interpreter,
117 if (!scope)
return nullptr;
119 const clang::Type* scope_type = scope->getAsType();
122 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
124 outer_scope = AddDefaultParametersNNS(Ctx, outer_scope, interpreter, normCtxt);
127 clang::QualType addDefault =
130 if (addDefault.getTypePtr() != scope_type)
131 return clang::NestedNameSpecifier::Create(Ctx,outer_scope,
133 addDefault.getTypePtr());
140static bool CheckDefinition(
const clang::CXXRecordDecl *cl,
const clang::CXXRecordDecl *context)
142 if (!cl->hasDefinition()) {
145 "Missing definition for class %s, please #include its header in the header of %s\n",
146 cl->getName().str().c_str(), context->getName().str().c_str());
149 "Missing definition for class %s\n",
150 cl->getName().str().c_str());
162static clang::NestedNameSpecifier *ReSubstTemplateArgNNS(
const clang::ASTContext &Ctxt,
163 clang::NestedNameSpecifier *scope,
166 if (!scope)
return nullptr;
168 const clang::Type* scope_type = scope->getAsType();
170 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
172 outer_scope = ReSubstTemplateArgNNS(Ctxt, outer_scope,
instance);
174 clang::QualType substScope =
177 scope = clang::NestedNameSpecifier::Create(Ctxt,outer_scope,
179 substScope.getTypePtr());
188 const clang::BuiltinType * builtin = llvm::dyn_cast<clang::BuiltinType>(
type->getCanonicalTypeInternal().getTypePtr());
190 return builtin->isInteger();
198static bool IsFieldDeclInt(
const clang::FieldDecl *field)
200 return IsTypeInt(field->getType().getTypePtr());
206static const clang::FieldDecl *GetDataMemberFromAll(
const clang::CXXRecordDecl &cl, llvm::StringRef
what)
208 clang::ASTContext &
C = cl.getASTContext();
209 clang::DeclarationName DName = &
C.Idents.get(
what);
210 auto R = cl.lookup(DName);
211 for (
const clang::NamedDecl *D :
R)
212 if (
auto FD = llvm::dyn_cast<const clang::FieldDecl>(D))
220static const clang::FieldDecl *GetDataMemberFromAllParents(clang::Sema &SemaR,
const clang::CXXRecordDecl &cl,
const char *
what)
222 clang::DeclarationName DName = &SemaR.Context.Idents.get(
what);
223 clang::LookupResult
R(SemaR, DName, clang::SourceLocation(),
224 clang::Sema::LookupOrdinaryName,
225 clang::Sema::ForExternalRedeclaration);
226 SemaR.LookupInSuper(
R, &
const_cast<clang::CXXRecordDecl&
>(cl));
229 return llvm::dyn_cast<const clang::FieldDecl>(
R.getFoundDecl());
233cling::LookupHelper::DiagSetting ToLHDS(
bool wantDiags) {
235 ? cling::LookupHelper::WithDiagnostics
236 : cling::LookupHelper::NoDiagnostics;
243namespace TMetaUtils {
252 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
253 "Tring to specify a number of template arguments to keep for a null pointer. Exiting without assigning any value.\n");
257 const clang::ClassTemplateDecl* canTempl = templ->getCanonicalDecl();
261 const std::string templateName (canTempl->getNameAsString());
262 const std::string i_str (std::to_string(i));
264 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
265 "Tring to specify for template %s %s arguments to keep, while before this number was %s\n",
266 canTempl->getNameAsString().c_str(),
268 previousArgsToKeep.c_str());
279 const clang::ClassTemplateDecl* constTempl = templ->getCanonicalDecl();
323 const std::string &normalizedName)
327 if (normalizedName.find(
"Double32_t") != std::string::npos
328 || normalizedName.find(
"Float16_t") != std::string::npos)
330 std::unique_ptr<clang::MangleContext> mangleCtx(rDecl->getASTContext().createMangleContext());
331 std::string mangledName;
333 llvm::raw_string_ostream sstr(mangledName);
334 if (
const clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(rDecl)) {
335 mangleCtx->mangleCXXRTTI(clang::QualType(TD->getTypeForDecl(), 0), sstr);
338 if (!mangledName.empty()) {
341 if (mangledName[0] ==
'\01')
342 mangledName.erase(0, 1);
344 if (!errDemangle && demangledTIName) {
345 static const char typeinfoNameFor[] =
" `RTTI Type Descriptor'";
346 if (strstr(demangledTIName, typeinfoNameFor)) {
347 std::string demangledName = demangledTIName;
348 demangledName.erase(demangledName.end() - strlen(typeinfoNameFor), demangledName.end());
351 if (!errDemangle && demangledTIName) {
352 static const char typeinfoNameFor[] =
"typeinfo for ";
353 if (!strncmp(demangledTIName, typeinfoNameFor, strlen(typeinfoNameFor))) {
354 std::string demangledName = demangledTIName + strlen(typeinfoNameFor);
356 free(demangledTIName);
357 return demangledName;
361 "Demangled typeinfo name '%s' does not contain `RTTI Type Descriptor'\n",
365 "Demangled typeinfo name '%s' does not start with 'typeinfo for'\n",
370 free(demangledTIName);
381 const clang::RecordDecl *decl,
384 bool rRequestNoInputOperator,
385 bool rRequestOnlyTClass,
386 int rRequestedVersionNumber,
387 const cling::Interpreter &interpreter,
401 const clang::RecordDecl *decl,
402 const char *requestName,
403 unsigned int nTemplateArgsToSkip,
406 bool rRequestNoInputOperator,
407 bool rRequestOnlyTClass,
408 int rRequestVersionNumber,
409 const cling::Interpreter &interpreter,
411 fRuleIndex(
index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
412 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
421 "Could not remove the requested template arguments.\n");
431 const clang::RecordDecl *decl,
432 const char *requestName,
435 bool rRequestNoInputOperator,
436 bool rRequestOnlyTClass,
437 int rRequestVersionNumber,
438 const cling::Interpreter &interpreter,
440 fRuleIndex(
index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer),
441 fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
455 const clang::RecordDecl *decl,
456 const char *requestName,
459 bool rRequestNoInputOperator,
460 bool rRequestOnlyTClass,
461 int rRequestVersionNumber,
462 const cling::Interpreter &interpreter,
464 fRuleIndex(
index), fDecl(decl), fRequestedName(
""), fRequestStreamerInfo(rStreamerInfo), fRequestNoStreamer(rNoStreamer), fRequestNoInputOperator(rRequestNoInputOperator), fRequestOnlyTClass(rRequestOnlyTClass), fRequestedVersionNumber(rRequestVersionNumber)
473 if (requestName && requestName[0]) {
488 ExistingTypeCheck_t existingTypeCheck,
489 AutoParse_t autoParse,
490 bool *shuttingDownPtr,
491 const int* pgDebug ):
492 fInterpreter(&interpreter),fNormalizedCtxt(&normCtxt),
493 fExistingTypeCheck(existingTypeCheck),
494 fAutoParse(autoParse),
495 fInterpreterIsShuttingDownPtr(shuttingDownPtr),
507 if (tname.empty())
return false;
517 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
518 clang::QualType t = lh.findType(nameLong, ToLHDS(
WantDiags()));
521 if (!
dest.isNull() && (
dest != t)) {
524 dest.getAsStringInternal(nameLong,
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
532 const std::string &nameLong)
534 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
535 clang::QualType t = lh.findType(nondef.c_str(), ToLHDS(
WantDiags()));
538 if (!
dest.isNull() && (
dest != t) &&
539 nameLong == t.getAsString(
fInterpreter->getCI()->getASTContext().getPrintingPolicy()))
549 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
550 const clang::Decl *scope = lh.findScope(base.c_str(), ToLHDS(
WantDiags()), 0);
557 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(scope);
558 isInlined = nsdecl && nsdecl->isInline();
570 if (tname.empty())
return false;
587 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
588 clang::QualType t = lh.findType(tname.c_str(), ToLHDS(
WantDiags()));
599 clang::PrintingPolicy policy(
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
600 policy.SuppressTagKeyword =
true;
601 policy.SuppressScope =
true;
610 if (strncmp(
result.c_str(),
"const ", 6) == 0) {
613 if (dropstd && strncmp(
result.c_str()+
offset,
"std::", 5) == 0) {
616 for(
unsigned int i = 1; i<
result.length(); ++i) {
619 if (dropstd &&
result.compare(i,5,
"std::",5) == 0) {
628 }
else if ( (i+1) <
result.length() &&
666 clang::QualType toSkip = lh.findType(
name, cling::LookupHelper::WithDiagnostics);
668 const clang::TypedefType *
tt = llvm::dyn_cast<clang::TypedefType>(
T);
670 clang::Decl* D =
tt->getDecl();
671 fConfig.m_toSkip.insert(D);
673 clang::QualType canon = toSkip->getCanonicalTypeInternal();
674 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),
T));
676 fTypeWithAlternative.insert(
T);
689 keepTypedef(lh,
"Double32_t");
690 keepTypedef(lh,
"Float16_t");
691 keepTypedef(lh,
"Long64_t",
true);
692 keepTypedef(lh,
"ULong64_t",
true);
694 clang::QualType toSkip = lh.findType(
"string", cling::LookupHelper::WithDiagnostics);
695 if (!toSkip.isNull()) {
696 if (
const clang::TypedefType* TT
697 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
698 fConfig.m_toSkip.insert(TT->getDecl());
700 toSkip = lh.findType(
"std::string", cling::LookupHelper::WithDiagnostics);
701 if (!toSkip.isNull()) {
702 if (
const clang::TypedefType* TT
703 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
704 fConfig.m_toSkip.insert(TT->getDecl());
706 clang::QualType canon = toSkip->getCanonicalTypeInternal();
707 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),toSkip.getTypePtr()));
718 return (cl.getKind() == clang::Decl::ClassTemplatePartialSpecialization
719 || cl.getKind() == clang::Decl::ClassTemplateSpecialization);
726 const cling::Interpreter& interp)
728 clang::Sema*
S = &interp.getSema();
729 const clang::NamedDecl* ND = cling::utils::Lookup::Named(
S,
name, cl);
730 if (ND == (clang::NamedDecl*)-1)
731 return (clang::FunctionDecl*)-1;
732 return llvm::dyn_cast_or_null<clang::FunctionDecl>(ND);
738const clang::CXXRecordDecl *
742 const cling::LookupHelper& lh = interp.getLookupHelper();
745 const clang::CXXRecordDecl *
result
746 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
747 (lh.findScope(
name, cling::LookupHelper::NoDiagnostics, resultType));
749 std::string std_name(
"std::");
753 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
754 (lh.findScope(std_name, cling::LookupHelper::NoDiagnostics, resultType));
764 clang::QualType qType(cl->getTypeForDecl(),0);
772 clang::Sema&
S = interp.getCI()->getSema();
775 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interp));
776 return S.RequireCompleteType(Loc,
Type, clang::diag::err_incomplete_type);
782 const clang::CXXRecordDecl *context,
const cling::Interpreter &interp)
788 if (!cl->getDefinition() || !cl->isCompleteDefinition()) {
792 if (!CheckDefinition(cl, context) || !CheckDefinition(base, context)) {
796 if (!base->hasDefinition()) {
800 return cl->isDerivedFrom(base);
812 const clang::NamedDecl *base
816 return IsBase(CRD, llvm::dyn_cast<clang::CXXRecordDecl>( base ),
817 llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext()),interp);
825 const clang::NamedDecl &forcontext,
826 const clang::QualType &qti,
827 const char *R__t,
int rwmode,
828 const cling::Interpreter &interp,
831 static const clang::CXXRecordDecl *TObject_decl
834 kBIT_ISTOBJECT = 0x10000000,
835 kBIT_HASSTREAMER = 0x20000000,
836 kBIT_ISSTRING = 0x40000000,
838 kBIT_ISPOINTER = 0x00001000,
839 kBIT_ISFUNDAMENTAL = 0x00000020,
840 kBIT_ISENUM = 0x00000008
853 clang::CXXRecordDecl *cxxtype = rawtype->getAsCXXRecordDecl() ;
855 int isTObj = cxxtype && (
IsBase(cxxtype,TObject_decl,
nullptr,interp) || rawname ==
"TObject");
859 if (ti.isPointerType()) kase |= kBIT_ISPOINTER;
860 if (rawtype->isFundamentalType()) kase |= kBIT_ISFUNDAMENTAL;
861 if (rawtype->isEnumeralType()) kase |= kBIT_ISENUM;
864 if (isTObj) kase |= kBIT_ISTOBJECT;
865 if (isStre) kase |= kBIT_HASSTREAMER;
866 if (tiName ==
"string") kase |= kBIT_ISSTRING;
867 if (tiName ==
"string*") kase |= kBIT_ISSTRING;
871 tcl =
" internal error in rootcling ";
877 if (R__t) finalString <<
" " << tiName <<
" " << R__t <<
";" << std::endl;
880 case kBIT_ISFUNDAMENTAL:
882 finalString <<
" R__b >> " << R__t <<
";" << std::endl;
885 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
887 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
896 finalString <<
" Int_t readtemp;" << std::endl
897 <<
" R__b >> readtemp;" << std::endl
898 <<
" " << R__t <<
" = static_cast<" << tiName <<
">(readtemp);" << std::endl;
901 case kBIT_HASSTREAMER:
902 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
904 finalString <<
" " << R__t <<
".Streamer(R__b);" << std::endl;
907 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
910 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
911 if (cxxtype && cxxtype->isAbstract()) {
912 finalString <<
" R__ASSERT(0);// " << objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
914 finalString <<
" " << R__t <<
" = new " << objType <<
";" << std::endl
915 <<
" " << R__t <<
"->Streamer(R__b);" << std::endl;
917 finalString <<
" } else {" << std::endl
918 <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl
919 <<
" }" << std::endl;
924 finalString <<
" {TString R__str;" << std::endl
925 <<
" R__str.Streamer(R__b);" << std::endl
926 <<
" " << R__t <<
" = R__str.Data();}" << std::endl;
929 case kBIT_ISSTRING|kBIT_ISPOINTER:
931 finalString <<
" {TString R__str;" << std::endl
932 <<
" R__str.Streamer(R__b);" << std::endl
933 <<
" " << R__t <<
" = new string(R__str.Data());}" << std::endl;
938 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
943 finalString <<
" R__b.StreamObject(&" << R__t <<
"," << tcl <<
");" << std::endl;
951 case kBIT_ISFUNDAMENTAL:
952 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
954 finalString <<
" R__b << " << R__t <<
";" << std::endl;
959 finalString <<
" { void *ptr_enum = (void*)&" << R__t <<
";\n";
960 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
963 case kBIT_HASSTREAMER:
964 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
966 finalString <<
" ((" << objType <<
"&)" << R__t <<
").Streamer(R__b);" << std::endl;
969 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
971 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
976 finalString <<
" {TString R__str(" << R__t <<
".c_str());" << std::endl
977 <<
" R__str.Streamer(R__b);};" << std::endl;
980 case kBIT_ISSTRING|kBIT_ISPOINTER:
982 finalString <<
" {TString R__str(" << R__t <<
"->c_str());" << std::endl
983 <<
" R__str.Streamer(R__b);}" << std::endl;
988 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
993 finalString <<
" R__b.StreamObject((" << objType <<
"*)&" << R__t <<
"," << tcl <<
");" << std::endl;
1005 clang::CXXRecordDecl* ncCl =
const_cast<clang::CXXRecordDecl*
>(cl);
1008 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1010 if (
auto* Ctor = interpreter.getCI()->getSema().LookupDefaultConstructor(ncCl)) {
1011 if (Ctor->getAccess() == clang::AS_public && !Ctor->isDeleted()) {
1024 const char *typeOfArg,
1025 const clang::CXXRecordDecl *expectedArgType,
1026 const cling::Interpreter& interpreter)
1028 if (typeOfArg && !expectedArgType) {
1029 const cling::LookupHelper& lh = interpreter.getLookupHelper();
1032 clang::QualType instanceType = lh.findType(typeOfArg, cling::LookupHelper::WithDiagnostics);
1033 if (!instanceType.isNull())
1034 expectedArgType = instanceType->getAsCXXRecordDecl();
1037 if (!expectedArgType)
1038 return EIOCtorCategory::kAbsent;
1041 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1042 for (
auto iter = cl->ctor_begin(), end = cl->ctor_end(); iter != end; ++iter)
1044 if ((iter->getAccess() != clang::AS_public) || (iter->getNumParams() != 1))
1048 clang::QualType argType((*iter->param_begin())->getType());
1049 argType = argType.getDesugaredType(cl->getASTContext());
1051 auto ioCtorCategory = EIOCtorCategory::kAbsent;
1052 if (argType->isPointerType()) {
1053 ioCtorCategory = EIOCtorCategory::kIOPtrType;
1054 argType = argType->getPointeeType();
1055 }
else if (argType->isReferenceType()) {
1056 ioCtorCategory = EIOCtorCategory::kIORefType;
1057 argType = argType.getNonReferenceType();
1061 argType = argType.getDesugaredType(cl->getASTContext());
1062 const clang::CXXRecordDecl *argDecl = argType->getAsCXXRecordDecl();
1064 if (argDecl->getCanonicalDecl() == expectedArgType->getCanonicalDecl()) {
1065 return ioCtorCategory;
1068 std::string realArg = argType.getAsString();
1069 std::string clarg(
"class ");
1071 if (realArg == clarg)
1072 return ioCtorCategory;
1076 return EIOCtorCategory::kAbsent;
1085 const cling::Interpreter& interpreter)
1087 const char *arg = ioctortype.
GetName();
1089 if (!ioctortype.
GetType() && (!arg || !arg[0])) {
1102 const char *method,
const char *
proto,
1103 const cling::Interpreter &interp,
1106 const clang::FunctionDecl* funcD
1107 = interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1108 diagnose ? cling::LookupHelper::WithDiagnostics
1109 : cling::LookupHelper::NoDiagnostics);
1111 return llvm::dyn_cast<const clang::CXXMethodDecl>(funcD);
1120 namespace TMetaUtils {
1123 const cling::LookupHelper& lh = interp.getLookupHelper();
1126 clang::QualType instanceType = lh.findType(type_of_arg, cling::LookupHelper::WithDiagnostics);
1127 if (!instanceType.isNull())
1128 fArgType = instanceType->getAsCXXRecordDecl();
1142 const cling::Interpreter &interp)
1144 if (cl->isAbstract())
return false;
1146 for (
auto & ctorType : ctorTypes) {
1150 if (EIOCtorCategory::kAbsent == ioCtorCat)
1153 std::string
proto( ctorType.GetName() );
1154 bool defaultCtor =
proto.empty();
1160 if (EIOCtorCategory::kIOPtrType == ioCtorCat) {
1162 }
else if (EIOCtorCategory::kIORefType == ioCtorCat) {
1166 arg +=
")nullptr )";
1169 const clang::CXXMethodDecl *method
1171 cling::LookupHelper::NoDiagnostics);
1172 if (method && method->getAccess() != clang::AS_public) {
1186 const cling::Interpreter& interp)
1188 if (!cl)
return false;
1190 if (cl->hasUserDeclaredDestructor()) {
1192 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
1193 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1195 return (
dest->getAccess() == clang::AS_public);
1207 const char *methodname,
1209 const cling::Interpreter &interp,
1212 const clang::CXXMethodDecl *method
1214 diagnose ? cling::LookupHelper::WithDiagnostics
1215 : cling::LookupHelper::NoDiagnostics);
1216 return (method && method->getAccess() == clang::AS_public);
1227 const char *
proto =
"TDirectory*";
1228 const char *
name =
"DirectoryAutoAdd";
1242 const char *
proto =
"TCollection*,TFileMergeInfo*";
1243 const char *
name =
"Merge";
1256 const char *
proto =
"TCollection*";
1257 const char *
name =
"Merge";
1272 const char *
proto =
"TFileMergeInfo*";
1273 const char *
name =
"ResetAfterMerge";
1283 const clang::CXXRecordDecl* clxx,
1284 const cling::Interpreter &interp,
1287 static const char *
proto =
"TBuffer&";
1289 const clang::CXXMethodDecl *method
1291 cling::LookupHelper::NoDiagnostics);
1292 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1294 return (method && method->getDeclContext() == clxx_as_context
1302 const clang::CXXRecordDecl* clxx,
1303 const cling::Interpreter &interp,
1306 static const char *
proto =
"TBuffer&,TClass*";
1308 const clang::CXXMethodDecl *method
1310 cling::LookupHelper::NoDiagnostics);
1311 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1313 return (method && method->getDeclContext() == clxx_as_context
1343 clang::QualType qualType(&
type,0);
1375 llvm::raw_string_ostream stream(qual_name);
1376 clang::PrintingPolicy policy( cl.getASTContext().getPrintingPolicy() );
1377 policy.SuppressTagKeyword =
true;
1378 policy.SuppressUnwrittenScope =
true;
1380 cl.getNameForDiagnostic(stream,policy,
true);
1383 if ( qual_name ==
"(anonymous " ) {
1384 size_t pos = qual_name.find(
':');
1385 qual_name.erase(0,pos+2);
1401 const clang::Type* declType ( recordDecl.getTypeForDecl() );
1402 clang::QualType qualType(declType,0);
1436 std::stringstream dims;
1437 std::string typenameStr;
1439 const clang::ASTContext& astContext = cl.getASTContext();
1442 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
1450 typenameStr.clear();
1454 clang::QualType fieldType(field_iter->getType());
1455 if (fieldType->isConstantArrayType()) {
1456 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(fieldType.getTypePtr());
1458 dims <<
"[" << arrayType->getSize().getLimitedValue() <<
"]";
1459 fieldType = arrayType->getElementType();
1460 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1470 for(clang::CXXRecordDecl::base_class_const_iterator iter = cl.bases_begin(), end = cl.bases_end();
1473 std::string basename( iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1483 const cling::Interpreter &interp,
1486 return interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1487 diagnose ? cling::LookupHelper::WithDiagnostics
1488 : cling::LookupHelper::NoDiagnostics);
1522 clang::SourceLocation sourceLocation = decl->getLocation();
1523 clang::SourceManager& sourceManager = decl->getASTContext().getSourceManager();
1525 if (!sourceLocation.isValid() ) {
1529 if (!sourceLocation.isFileID()) {
1530 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
1533 if (sourceLocation.isValid() && sourceLocation.isFileID()) {
1534 return sourceManager.getLineNumber(sourceManager.getFileID(sourceLocation),sourceManager.getFileOffset(sourceLocation));
1547 while (llvm::isa<clang::PointerType>(instanceType.getTypePtr())
1548 || llvm::isa<clang::ReferenceType>(instanceType.getTypePtr()))
1550 instanceType = instanceType->getPointeeType();
1553 const clang::ElaboratedType* etype
1554 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
1556 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1569 const clang::CXXRecordDecl* clxx = instanceType->getAsCXXRecordDecl();
1570 if (clxx && clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1572 const clang::TemplateSpecializationType* TST
1573 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
1580 for(clang::TemplateSpecializationType::iterator
1581 I = TST->begin(),
E = TST->end();
1599 const cling::Interpreter &interp,
1602 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1603 if (!clxx || clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return false;
1605 clang::QualType instanceType = interp.getLookupHelper().findType(cl.
GetNormalizedName(),
1606 cling::LookupHelper::WithDiagnostics);
1607 if (instanceType.isNull()) {
1620 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(attribute);
1625 attrString = annAttr->getAnnotation();
1635 if (substrFound==std::string::npos) {
1640 attrName = attributeStr.substr(0, EndPart1);
1642 attrValue = attributeStr.substr(EndPart1 + separatorLength);
1650 std::string attrString;
1652 if (0!=ret)
return ret;
1660 const std::string& propName,
1661 std::string& propValue)
1663 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1664 attrIt!=decl.attr_end();++attrIt){
1665 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1666 if (!annAttr)
continue;
1668 llvm::StringRef attribute = annAttr->getAnnotation();
1669 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1670 if (split.first != propName.c_str())
continue;
1672 propValue = split.second;
1683 const std::string& propName,
1686 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1687 attrIt!=decl.attr_end();++attrIt){
1688 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1689 if (!annAttr)
continue;
1691 llvm::StringRef attribute = annAttr->getAnnotation();
1692 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1693 if (split.first != propName.c_str())
continue;
1695 return split.second.getAsInteger(10,propValue);
1706 const clang::CXXRecordDecl *decl,
1707 const cling::Interpreter &interp,
1710 bool& needCollectionProxy)
1714 std::string mappedname;
1716 std::string csymbol = classname;
1724 csymbol.insert(0,
"::");
1731 const cling::LookupHelper& lh = interp.getLookupHelper();
1734 bool isStdNotString = isStd && !isString;
1736 finalString <<
"namespace ROOT {" <<
"\n";
1740 finalString <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();\n"
1741 <<
" static void " << mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1747 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p = nullptr);" <<
"\n";
1751 finalString <<
" static void *newArray_";
1752 finalString << mappedname.c_str();
1753 finalString <<
"(Long_t size, void *p);";
1754 finalString <<
"\n";
1759 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";
1762 finalString <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1765 finalString <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1768 finalString <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1771 finalString <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1774 finalString <<
" static void reset_" << mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1781 ROOT::SchemaRuleClassMap_t::iterator rulesIt1 =
ROOT::gReadRules.find( classname.c_str() );
1782 ROOT::SchemaRuleClassMap_t::iterator rulesIt2 =
ROOT::gReadRawRules.find( classname.c_str() );
1793 finalString <<
"\n // Schema evolution read functions\n";
1794 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt1->second.begin();
1795 while( rIt != rulesIt1->second.end() ) {
1801 std::string error_string;
1803 Warning(0,
"%s", error_string.c_str());
1804 rIt = rulesIt1->second.erase(rIt);
1812 if( rIt->find(
"code" ) != rIt->end() ) {
1828 finalString <<
"\n // Schema evolution read raw functions\n";
1829 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt2->second.begin();
1830 while( rIt != rulesIt2->second.end() ) {
1836 std::string error_string;
1838 Warning(0,
"%s", error_string.c_str());
1839 rIt = rulesIt2->second.erase(rIt);
1847 if( rIt->find(
"code" ) == rIt->end() )
1855 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1857 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " << csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1859 finalString <<
" " << csymbol <<
" *ptr = nullptr;" <<
"\n";
1863 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " << csymbol <<
" >(nullptr);" <<
"\n";
1866 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol <<
"));" <<
"\n";
1868 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1871 finalString << csymbol <<
"::Class_Version(), ";
1873 finalString <<
"2, ";
1875 finalString <<
"-2, ";
1881 static const char *versionFunc =
"GetClassVersion";
1885 std::string
proto = classname +
"*";
1886 const clang::Decl* ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1887 const clang::FunctionDecl *methodinfo
1889 interp, cling::LookupHelper::NoDiagnostics);
1897 finalString <<
"GetClassVersion< ";
1898 finalString << classname.c_str();
1899 finalString <<
" >(), ";
1908 for (
unsigned int i=0; i<
filename.length(); i++) {
1913 <<
"," <<
"\n" <<
" typeid(" << csymbol
1914 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1917 finalString <<
"&" << csymbol <<
"::Dictionary, ";
1919 finalString <<
"&" << mappedname <<
"_Dictionary, ";
1923 TClassTable__kHasCustomStreamerMember = 0x10
1928 rootflag = rootflag | TClassTable__kHasCustomStreamerMember;
1930 finalString <<
"isa_proxy, " << rootflag <<
"," <<
"\n" <<
" sizeof(" << csymbol <<
") );" <<
"\n";
1932 finalString <<
" instance.SetNew(&new_" << mappedname.c_str() <<
");" <<
"\n";
1934 finalString <<
" instance.SetNewArray(&newArray_" << mappedname.c_str() <<
");" <<
"\n";
1937 finalString <<
" instance.SetDelete(&delete_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" << mappedname.c_str() <<
");" <<
"\n";
1940 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" << mappedname.c_str() <<
");" <<
"\n";
1944 finalString <<
" instance.SetStreamerFunc(&streamer_" << mappedname.c_str() <<
");" <<
"\n";
1948 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" << mappedname.c_str() <<
");" <<
"\n";
1951 finalString <<
" instance.SetMerge(&merge_" << mappedname.c_str() <<
");" <<
"\n";
1954 finalString <<
" instance.SetResetAfterMerge(&reset_" << mappedname.c_str() <<
");" <<
"\n";
1957 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
1959 needCollectionProxy =
true;
1960 }
else if (stl != 0 &&
1963 int idx = classname.find(
"<");
1965 const char* methodTCP=0;
1971 methodTCP=
"Pushback";
1974 methodTCP=
"Pushfront";
1980 methodTCP=
"MapInsert";
1992 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << methodTCP <<
"< " << classNameForIO.c_str() <<
" >()));" <<
"\n";
1994 needCollectionProxy =
true;
2002 finalString <<
"\n" <<
" ::ROOT::AddClassAlternate(\""
2009 finalString <<
"\n" <<
" ::ROOT::AddClassAlternate(\""
2019 finalString <<
"\n" <<
" ::ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
2023 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrules(" << rulesIt1->second.size() <<
");" <<
"\n";
2025 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
2029 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrawrules(" << rulesIt2->second.size() <<
");" <<
"\n";
2031 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
2034 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
2038 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " << csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal((" << csymbol <<
"*)nullptr);\n }" <<
"\n";
2041 finalString <<
" // Static variable to force the class initialization" <<
"\n";
2045 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal((const " << csymbol <<
"*)nullptr); R__UseDummy(_R__UNIQUE_DICT_(Init));" <<
"\n";
2048 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n"
2049 <<
" static TClass *" << mappedname <<
"_Dictionary() {\n"
2050 <<
" TClass* theClass ="
2051 <<
"::ROOT::GenerateInitInstanceLocal((const " << csymbol <<
"*)nullptr)->GetClass();\n"
2052 <<
" " << mappedname <<
"_TClassManip(theClass);\n";
2053 finalString <<
" return theClass;\n";
2054 finalString <<
" }\n\n";
2058 std::string manipString;
2059 std::string attribute_s;
2060 std::string attrName, attrValue;
2062 bool attrMapExtracted =
false;
2063 if (decl->hasAttrs()){
2065 for (clang::Decl::attr_iterator attrIt = decl->attr_begin();
2066 attrIt!=decl->attr_end();++attrIt){
2073 if (attrName ==
"name" ||
2074 attrName ==
"pattern" ||
2075 attrName ==
"rootmap")
continue;
2081 if (!attrMapExtracted){
2082 manipString+=
" theClass->CreateAttributeMap();\n";
2083 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2084 attrMapExtracted=
true;
2086 manipString+=
" attrMap->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2092 for(clang::CXXRecordDecl::decl_iterator internalDeclIt = decl->decls_begin();
2093 internalDeclIt != decl->decls_end(); ++internalDeclIt){
2094 if (!(!(*internalDeclIt)->isImplicit()
2095 && (clang::isa<clang::FieldDecl>(*internalDeclIt) ||
2096 clang::isa<clang::VarDecl>(*internalDeclIt))))
continue;
2099 if (!internalDeclIt->hasAttrs())
continue;
2101 attrMapExtracted =
false;
2102 bool memberPtrCreated =
false;
2104 for (clang::Decl::attr_iterator attrIt = internalDeclIt->attr_begin();
2105 attrIt!=internalDeclIt->attr_end();++attrIt){
2113 clang::NamedDecl* namedInternalDecl = clang::dyn_cast<clang::NamedDecl> (*internalDeclIt);
2114 if (!namedInternalDecl) {
2118 const std::string memberName(namedInternalDecl->getName());
2119 const std::string cppMemberName=
"theMember_"+memberName;
2122 const std::string dataMemberCreation=
" TDataMember* "+cppMemberName+
" = theClass->GetDataMember(\""+memberName+
"\");\n";
2135 if (!memberPtrCreated){
2136 manipString+=dataMemberCreation;
2137 memberPtrCreated=
true;
2140 if (!attrMapExtracted){
2141 manipString+=
" "+cppMemberName+
"->CreateAttributeMap();\n";
2142 manipString+=
" TDictAttributeMap* memberAttrMap_"+memberName+
"( theMember_"+memberName+
"->GetAttributeMap() );\n";
2143 attrMapExtracted=
true;
2146 manipString+=
" memberAttrMap_"+memberName+
"->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2153 finalString <<
" static void " << mappedname <<
"_TClassManip(TClass* " << (manipString.empty() ?
"":
"theClass") <<
"){\n"
2158 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2168 std::string &clsname,
2169 std::string &nsname,
2170 const clang::CXXRecordDecl *cl)
2180 auto ctxt = cl->getEnclosingNamespaceContext();
2181 while(ctxt && ctxt!=cl && ctxt->isInlineNamespace()) {
2182 ctxt = ctxt->getParent();
2185 const clang::NamedDecl *namedCtxt = llvm::dyn_cast<clang::NamedDecl>(ctxt);
2186 if (namedCtxt && namedCtxt!=cl) {
2187 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(namedCtxt);
2188 if (nsdecl != 0 && !nsdecl->isAnonymousNamespace()) {
2190 clsname.erase (0, nsname.size() + 2);
2202 const clang::DeclContext *ctxt = cl.getDeclContext();
2203 while(ctxt && !ctxt->isNamespace()) {
2204 ctxt = ctxt->getParent();
2218 int closing_brackets = 0;
2222 if (ctxt && ctxt->isNamespace()) {
2224 const clang::NamespaceDecl *
ns = llvm::dyn_cast<clang::NamespaceDecl>(ctxt);
2230 out <<
"namespace " <<
ns->getNameAsString() <<
" {" << std::endl;
2235 return closing_brackets;
2249 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2250 if (kind == clang::TSK_Undeclared ) {
2253 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2267 const char *
name = which;
2268 const char *
proto =
"size_t";
2269 const char *protoPlacement =
"size_t,void*";
2272 const clang::FunctionDecl *operatornew
2275 cling::LookupHelper::NoDiagnostics);
2276 const clang::FunctionDecl *operatornewPlacement
2278 name, protoPlacement, interp,
2279 cling::LookupHelper::NoDiagnostics);
2281 const clang::DeclContext *ctxtnew = 0;
2282 const clang::DeclContext *ctxtnewPlacement = 0;
2285 ctxtnew = operatornew->getParent();
2287 if (operatornewPlacement) {
2288 ctxtnewPlacement = operatornewPlacement->getParent();
2294 operatornewPlacement
2299 ctxtnew = operatornew->getParent();
2301 if (operatornewPlacement) {
2302 ctxtnewPlacement = operatornewPlacement->getParent();
2305 if (ctxtnewPlacement == 0) {
2313 if (ctxtnew == ctxtnewPlacement) {
2317 const clang::CXXRecordDecl* clnew = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnew);
2318 const clang::CXXRecordDecl* clnewPlacement = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnewPlacement);
2319 if (clnew == 0 && clnewPlacement == 0) {
2325 if (clnew != 0 && clnewPlacement == 0) {
2329 if (clnew == 0 && clnewPlacement != 0) {
2334 if (clnew->isDerivedFrom(clnewPlacement)) {
2364 const clang::CXXRecordDecl *decl,
2365 const cling::Interpreter &interp,
2371 std::string mappedname;
2389 classname.insert(0,
"::");
2392 finalString <<
"namespace ROOT {" <<
"\n";
2397 finalString <<
" // Wrappers around operator new" <<
"\n";
2398 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2400 finalString <<
"new(p) ";
2401 finalString << classname.c_str();
2402 finalString << args;
2403 finalString <<
" : ";
2405 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2406 finalString << classname.c_str();
2407 finalString << args;
2408 finalString <<
" : ";
2410 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2411 finalString <<
" }" <<
"\n";
2415 finalString <<
" static void *newArray_";
2416 finalString << mappedname.c_str();
2417 finalString <<
"(Long_t nElements, void *p) {";
2418 finalString <<
"\n";
2419 finalString <<
" return p ? ";
2421 finalString <<
"new(p) ";
2422 finalString << classname.c_str();
2423 finalString <<
"[nElements] : ";
2425 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2426 finalString << classname.c_str();
2427 finalString <<
"[nElements] : ";
2429 finalString <<
"new ";
2430 finalString << classname.c_str();
2431 finalString <<
"[nElements];";
2432 finalString <<
"\n";
2433 finalString <<
" }";
2434 finalString <<
"\n";
2439 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";
2443 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";
2447 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";
2451 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";
2455 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";
2457 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";
2461 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";
2463 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2470 const cling::Interpreter &interp,
2477 if (version == 0)
return;
2481 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2482 if (clxx == 0)
return;
2485 for(clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
2491 Internal::RStl::Instance().GenerateTClassFor( iter->getType(), interp, normCtxt);
2496 for(clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
2500 std::string mTypename;
2506 if (!strcmp(shortTypeName,
"string")) {
2518 Internal::RStl::Instance().GenerateTClassFor(utype, interp, normCtxt);
2528 const clang::Type *rawtype =
m.getType()->getCanonicalTypeInternal().getTypePtr();
2529 if (rawtype->isArrayType()) {
2530 rawtype = rawtype->getBaseElementTypeUnsafe ();
2544 const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2553 if (!funcCV)
return -1;
2556 if (funcCV == (clang::FunctionDecl*)-1)
return 1;
2571 using res_t = std::pair<bool, int>;
2573 const clang::CompoundStmt* FuncBody
2574 = llvm::dyn_cast_or_null<clang::CompoundStmt>(funcCV->getBody());
2576 return res_t{
false, -1};
2577 if (FuncBody->size() != 1) {
2581 return res_t{
false, -1};
2583 const clang::ReturnStmt* RetStmt
2584 = llvm::dyn_cast<clang::ReturnStmt>(FuncBody->body_back());
2586 return res_t{
false, -1};
2587 const clang::Expr* RetExpr = RetStmt->getRetValue();
2593 llvm::APSInt RetRes;
2594 if (!RetExpr->isIntegerConstantExpr(RetRes, funcCV->getASTContext()))
2595 return res_t{
false, -1};
2596 if (RetRes.isSigned()) {
2597 return res_t{
true, (
Version_t)RetRes.getSExtValue()};
2600 return res_t{
true, (
Version_t)RetRes.getZExtValue()};
2616 clang::QualType
type =
m.getType();
2628 clang::QualType
type = base.getType();
2641 const std::function<
void(
const clang::Module::Header &)> &closure,
2642 bool includeDirectlyUsedModules)
2651 const std::size_t publicHeaderIndex = 4;
2654 const std::size_t maxArrayLength = ((
sizeof module.Headers) / (
sizeof *module.Headers));
2655 static_assert(publicHeaderIndex + 1 == maxArrayLength,
2656 "'Headers' has changed it's size, we need to update publicHeaderIndex");
2661 llvm::SetVector<const clang::Module *> modules;
2662 modules.insert(&module);
2663 for (
size_t i = 0; i < modules.size(); ++i) {
2664 const clang::Module *M = modules[i];
2665 for (
const clang::Module *subModule : M->submodules())
2666 modules.insert(subModule);
2669 for (
const clang::Module *
m : modules) {
2670 if (includeDirectlyUsedModules) {
2671 for (clang::Module *used :
m->DirectUses) {
2676 for (std::size_t i = 0; i < publicHeaderIndex; i++) {
2677 auto &headerList =
m->Headers[i];
2678 for (
const clang::Module::Header &moduleHeader : headerList) {
2679 closure(moduleHeader);
2693 static char t[4096];
2694 static const char* constwd =
"const ";
2695 static const char* constwdend =
"const";
2700 for (
s=typeDesc;*
s;
s++) {
2703 if (lev==0 && *
s==
'*')
continue;
2704 if (lev==0 && (strncmp(constwd,
s,strlen(constwd))==0
2705 ||strcmp(constwdend,
s)==0 ) ) {
2706 s+=strlen(constwd)-1;
2709 if (lev==0 && *
s==
' ' && *(
s+1)!=
'*') {
p = t;
continue;}
2710 if (
p - t > (
long)
sizeof(t)) {
2711 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2724 const cling::Interpreter& interp)
2732 clang::QualType
type =
m.getType();
2734 if (
type->isReferenceType()) {
2739 std::string mTypeName =
type.getAsString(
m.getASTContext().getPrintingPolicy());
2740 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2743 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2751 const clang::Type *rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
2753 if (rawtype->isPointerType()) {
2755 clang::QualType pointee;
2756 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2758 rawtype = pointee.getTypePtr();
2762 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2767 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2771 if (version > 0)
return true;
2787 clang::QualType pointee;
2788 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2790 rawtype = pointee.getTypePtr();
2804 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2808 return rawtype->getAsCXXRecordDecl();
2817 const cling::Interpreter &interp,
2819 std::ostream& dictStream,
2821 bool isGenreflex=
false)
2823 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2825 if (!decl || !decl->isCompleteDefinition()) {
2829 std::string fullname;
2832 Internal::RStl::Instance().GenerateTClassFor(cl.
GetNormalizedName(), llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl()), interp, normCtxt);
2841 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2843 ROOT::TMetaUtils::Info(0,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2865 const cling::Interpreter &interpreter,
2868 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2870 clang::QualType originalType = instanceType;
2874 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2876 clang::Qualifiers quals = instanceType.getQualifiers();
2877 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2878 if (newPointee != instanceType->getPointeeType()) {
2879 instanceType = Ctx.getPointerType(newPointee);
2881 instanceType = Ctx.getQualifiedType(instanceType, quals);
2883 return instanceType;
2888 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2890 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2891 clang::Qualifiers quals = instanceType.getQualifiers();
2892 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2894 if (newPointee != instanceType->getPointeeType()) {
2897 instanceType = Ctx.getLValueReferenceType(newPointee);
2899 instanceType = Ctx.getRValueReferenceType(newPointee);
2901 instanceType = Ctx.getQualifiedType(instanceType, quals);
2903 return instanceType;
2907 bool prefix_changed =
false;
2908 clang::NestedNameSpecifier* prefix = 0;
2909 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2910 const clang::ElaboratedType* etype
2911 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2914 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2915 prefix_changed = prefix != etype->getQualifier();
2916 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2922 const clang::TemplateSpecializationType* TST
2923 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2925 const clang::ClassTemplateSpecializationDecl* TSTdecl
2926 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2938 bool mightHaveChanged =
false;
2939 if (TST && TSTdecl) {
2941 clang::Sema&
S = interpreter.getCI()->getSema();
2942 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2943 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2944 clang::TemplateParameterList::iterator Param = Params->
begin();
2948 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2950 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2951 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2952 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2953 for(clang::TemplateSpecializationType::iterator
2954 I = TST->begin(),
E = TST->end();
2956 I!=
E ? ++
I : 0, ++Idecl, ++Param) {
2960 if (
I->getKind() == clang::TemplateArgument::Template) {
2961 clang::TemplateName templateName =
I->getAsTemplate();
2962 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2964 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2966 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2967 clang::NamespaceDecl*
ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2968 clang::NestedNameSpecifier* nns;
2970 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,
ns);
2971 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2972 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2975 desArgs.push_back(*
I);
2978 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, templateDecl) );
2979 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2980 mightHaveChanged =
true;
2987 desArgs.push_back(*
I);
2991 clang::QualType SubTy =
I->getAsType();
3000 if (SubTy != newSubTy) {
3001 mightHaveChanged =
true;
3002 desArgs.push_back(clang::TemplateArgument(newSubTy));
3004 desArgs.push_back(*
I);
3007 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
3009 mightHaveChanged =
true;
3011 const clang::TemplateArgument& templateArg
3012 = TSTdecl->getTemplateArgs().get(Idecl);
3014 desArgs.push_back(templateArg);
3017 clang::QualType SubTy = templateArg.getAsType();
3019 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3020 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
3022 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
3025 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
3026 clang::sema::HackForDefaultTemplateArg raii;
3027 bool HasDefaultArgs;
3028 clang::TemplateArgumentLoc ArgType =
S.SubstDefaultTemplateArgumentIfAvailable(
3037 if (ArgType.getArgument().isNull()
3040 "Template parameter substitution failed for %s around %s\n",
3041 instanceType.getAsString().c_str(), SubTy.getAsString().c_str());
3044 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
3045 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
3048 desArgs.push_back(clang::TemplateArgument(SubTy));
3057 if (mightHaveChanged) {
3058 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
3060 TST->getCanonicalTypeInternal());
3064 if (!prefix_changed && !mightHaveChanged)
return originalType;
3066 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
3067 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
3069 return instanceType;
3089 llvm::StringRef title;
3092 if (clang::AnnotateAttr *
A =
m.getAttr<clang::AnnotateAttr>())
3093 title =
A->getAnnotation();
3105 if (errnum) *errnum =
VALID;
3107 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3108 size_t rightbracket = title.find(
']');
3109 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3111 std::string working;
3112 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
3119 size_t indexvarlen = indexvar.size();
3120 for ( i=0; i<indexvarlen; i++) {
3121 if (!isspace(indexvar[i])) {
3122 working += indexvar[i];
3127 const char *tokenlist =
"*+-";
3128 char *current =
const_cast<char*
>(working.c_str());
3129 current = strtok(current,tokenlist);
3131 while (current!=0) {
3133 if (isdigit(current[0])) {
3134 for(i=0;i<strlen(current);i++) {
3135 if (!isdigit(current[i])) {
3140 if (errstr) *errstr = current;
3141 if (errnum) *errnum =
NOT_INT;
3142 return llvm::StringRef();
3147 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext());
3148 const clang::FieldDecl *index1 =
nullptr;
3150 index1 = GetDataMemberFromAll(*parent_clxx, current );
3152 if ( IsFieldDeclInt(index1) ) {
3157 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3161 if ( field_iter->getNameAsString() ==
m.getNameAsString() ) {
3167 if (errstr) *errstr = current;
3168 if (errnum) *errnum =
NOT_DEF;
3169 return llvm::StringRef();
3171 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3179 if (errstr) *errstr = current;
3180 if (errnum) *errnum =
NOT_INT;
3181 return llvm::StringRef();
3188 clang::Sema& SemaR =
const_cast<cling::Interpreter&
>(interp).getSema();
3189 index1 = GetDataMemberFromAllParents(SemaR, *parent_clxx, current);
3192 if ( IsFieldDeclInt(index1) ) {
3199 if (errnum) *errnum =
NOT_INT;
3200 if (errstr) *errstr = current;
3204 if (errnum) *errnum =
NOT_INT;
3205 if (errstr) *errstr = current;
3206 return llvm::StringRef();
3208 if ( found && (index1->getAccess() == clang::AS_private) ) {
3211 if (errstr) *errstr = current;
3213 return llvm::StringRef();
3220 if (errstr) *errstr = indexvar;
3221 if (errnum) *errnum =
UNKNOWN;
3222 return llvm::StringRef();
3227 current = strtok(0,tokenlist);
3243 while((
c = in[i++])) {
3244 const char *repl =
nullptr;
3246 case '+': repl =
"pL";
break;
3247 case '-': repl =
"mI";
break;
3248 case '*': repl =
"mU";
break;
3249 case '/': repl =
"dI";
break;
3250 case '&': repl =
"aN";
break;
3251 case '%': repl =
"pE";
break;
3252 case '|': repl =
"oR";
break;
3253 case '^': repl =
"hA";
break;
3254 case '>': repl =
"gR";
break;
3255 case '<': repl =
"lE";
break;
3256 case '=': repl =
"eQ";
break;
3257 case '~': repl =
"wA";
break;
3258 case '.': repl =
"dO";
break;
3259 case '(': repl =
"oP";
break;
3260 case ')': repl =
"cP";
break;
3261 case '[': repl =
"oB";
break;
3262 case ']': repl =
"cB";
break;
3263 case '!': repl =
"nO";
break;
3264 case ',': repl =
"cO";
break;
3265 case '$': repl =
"dA";
break;
3266 case ' ': repl =
"sP";
break;
3267 case ':': repl =
"cL";
break;
3268 case '"': repl =
"dQ";
break;
3269 case '@': repl =
"aT";
break;
3270 case '\'': repl =
"sQ";
break;
3271 case '\\': repl =
"fI";
break;
3280 auto firstNonNumber = out.find_first_not_of(
"0123456789");
3281 if (firstNonNumber != std::string::npos)
3282 out.replace(0,firstNonNumber,
"");
3285static clang::SourceLocation
3287 clang::SourceLocation sourceLoc) {
3289 if (!sourceLoc.isFileID()) {
3290 return sourceManager.getExpansionRange(sourceLoc).getEnd();
3299 const cling::Interpreter& interp)
3329 using namespace clang;
3330 SourceLocation headerLoc = decl.getLocation();
3332 static const char invalidFilename[] =
"";
3333 if (!headerLoc.isValid())
return invalidFilename;
3335 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3337 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3339 FileID headerFID = sourceManager.getFileID(headerLoc);
3340 SourceLocation includeLoc
3342 sourceManager.getIncludeLoc(headerFID));
3344 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3345 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3346 const DirectoryLookup *foundDir = 0;
3349 assert(headerFE &&
"Couldn't find FileEntry from FID!");
3350 const FileEntry *FEhdr
3354 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3362 headerFID = sourceManager.getFileID(includeLoc);
3363 headerFE = sourceManager.getFileEntryForID(headerFID);
3368 if (interp.getCI()->getLangOpts().Modules && !headerFE) {
3369 assert(decl.isFirstDecl() &&
"Couldn't trace back include from a decl"
3370 " that is not from an AST file");
3371 assert(StringRef(includeLoc.printToString(sourceManager)).startswith(
"<module-includes>"));
3375 sourceManager.getIncludeLoc(headerFID));
3378 if (!headerFE)
return invalidFilename;
3380 llvm::SmallString<256> headerFileName(headerFE->getName());
3383 llvm::sys::path::remove_dots(headerFileName,
true);
3394 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3395 const FileEntry* FELong = 0;
3397 for (llvm::sys::path::const_iterator
3398 IDir = llvm::sys::path::begin(headerFileName),
3399 EDir = llvm::sys::path::end(headerFileName);
3400 !FELong && IDir != EDir; ++IDir) {
3406 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3407 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3408 assert(trailingPart.data() + trailingPart.size()
3409 == headerFileName.data() + headerFileName.size()
3410 &&
"Mismatched partitioning of file name!");
3411 const DirectoryLookup* FoundDir = 0;
3412 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3414 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3422 return invalidFilename;
3426 for (llvm::sys::path::reverse_iterator
3427 IDir = llvm::sys::path::rbegin(headerFileName),
3428 EDir = llvm::sys::path::rend(headerFileName);
3429 IDir != EDir; ++IDir) {
3430 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3431 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3432 assert(trailingPart.data() + trailingPart.size()
3433 == headerFileName.data() + headerFileName.size()
3434 &&
"Mismatched partitioning of file name!");
3435 const DirectoryLookup* FoundDir = 0;
3438 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3440 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3443 0,
nullptr ) == FELong) {
3444 return trailingPart;
3448 return invalidFilename;
3454 const clang::QualType &qtype,
3455 const clang::ASTContext &astContext)
3457 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3466 const clang::QualType &qtype,
3467 const cling::Interpreter &interpreter)
3472 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3476 interpreter.getCI()->getASTContext());
3484 clang::ClassTemplateDecl*& ctd,
3485 clang::ClassTemplateSpecializationDecl*& ctsd)
3487 using namespace clang;
3488 const Type* theType = qt.getTypePtr();
3495 if (theType->isPointerType()) {
3499 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3500 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3502 ctd = ctsd->getSpecializedTemplate();
3507 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3512 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3514 ctd = ctsd->getSpecializedTemplate();
3529 using namespace clang;
3530 ClassTemplateSpecializationDecl* ctsd;
3531 ClassTemplateDecl* ctd;
3545 using namespace clang;
3546 TemplateName theTemplateName;
3548 const Type* theType = qt.getTypePtr();
3550 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3551 theTemplateName = tst->getTemplateName();
3554 theTemplateName = TemplateName(ctd);
3557 return theTemplateName;
3563 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3564 const clang::NamedDecl& tPar,
3565 const cling::Interpreter& interp,
3569 using namespace clang;
3572 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3573 if (!ttpdPtr)
return false;
3574 if (!ttpdPtr->hasDefaultArgument())
return false;
3577 QualType tParQualType = ttpdPtr->getDefaultArgument();
3578 const QualType tArgQualType = tArg.getAsType();
3585 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3596 const clang::ElaboratedType* etype
3597 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3599 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3600 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3603 const TemplateSpecializationType* tst =
3604 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3609 ClassTemplateSpecializationDecl* TSTdecl
3610 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3615 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3618 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3621 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3626 TemplateArgument newArg = tArg;
3628 clang::Sema&
S = interp.getCI()->getSema();
3629 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
3630 clang::sema::HackForDefaultTemplateArg raii;
3631 bool HasDefaultArgs;
3632 TemplateArgumentLoc defTArgLoc =
S.SubstDefaultTemplateArgumentIfAvailable(Template,
3640 newArg = defTArgLoc.getArgument();
3641 if (newArg.isNull() ||
3644 "Template parameter substitution failed!");
3647 ClassTemplateSpecializationDecl* nTSTdecl
3648 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3651 isEqual = (nTSTdecl && nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl()) ||
3652 (tParQualType.getTypePtr() == newArg.getAsType().getTypePtr());
3664 const clang::NamedDecl& tPar)
3666 using namespace clang;
3667 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3668 if (!nttpdPtr)
return false;
3669 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3671 if (!nttpd.hasDefaultArgument())
3675 llvm::APSInt defaultValueAPSInt(64,
false);
3676 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3677 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3678 defArgExpr->isIntegerConstantExpr(defaultValueAPSInt, astCtxt);
3681 const int value = tArg.getAsIntegral().getLimitedValue();
3684 return value == defaultValueAPSInt;
3694 using namespace clang;
3695 if (!nDecl)
return false;
3696 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3697 return ttpd->hasDefaultArgument();
3698 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3699 return nttpd->hasDefaultArgument();
3704static void KeepNParams(clang::QualType& normalizedType,
3705 const clang::QualType& vanillaType,
3706 const cling::Interpreter& interp,
3711 const clang::TemplateArgument &tArg,
3712 const cling::Interpreter& interp,
3714 const clang::ASTContext& astCtxt)
3717 using namespace clang;
3725 QualType thisNormQualType = normTArg.getAsType();
3726 QualType thisArgQualType = tArg.getAsType();
3731 normTArg = TemplateArgument(thisNormQualType);
3732 return (thisNormQualType != thisArgQualType);
3733 }
else if (normTArg.getKind() == clang::TemplateArgument::Pack) {
3734 assert( tArg.getKind() == clang::TemplateArgument::Pack );
3736 SmallVector<TemplateArgument, 2> desArgs;
3737 bool mightHaveChanged =
true;
3738 for (
auto I = normTArg.pack_begin(),
E = normTArg.pack_end(),
3739 FI = tArg.pack_begin(), FE = tArg.pack_end();
3740 I !=
E && FI != FE; ++
I, ++FI)
3742 TemplateArgument pack_arg(*
I);
3744 desArgs.push_back(pack_arg);
3746 if (mightHaveChanged) {
3747 ASTContext &mutableCtx(
const_cast<ASTContext&
>(astCtxt) );
3748 normTArg = TemplateArgument::CreatePackCopy(mutableCtx, desArgs);
3750 return mightHaveChanged;
3761 const clang::QualType& vanillaType,
3762 const cling::Interpreter& interp,
3766 using namespace clang;
3770 ClassTemplateSpecializationDecl* ctsd;
3771 ClassTemplateDecl* ctd;
3778 QualType originalNormalizedType = normalizedType;
3780 const ASTContext& astCtxt = ctsd->getASTContext();
3785 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3787 clang::Qualifiers quals = normalizedType.getQualifiers();
3788 auto valNormalizedType = normalizedType->getPointeeType();
3789 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3790 normalizedType = astCtxt.getPointerType(valNormalizedType);
3792 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3798 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3800 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3801 clang::Qualifiers quals = normalizedType.getQualifiers();
3802 auto valNormType = normalizedType->getPointeeType();
3803 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3807 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3809 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3811 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3816 bool prefix_changed =
false;
3817 clang::NestedNameSpecifier* prefix =
nullptr;
3818 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3819 const clang::ElaboratedType* etype
3820 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3824 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3825 prefix_changed = prefix != etype->getQualifier();
3826 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3832 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3833 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3834 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3835 if (tpl->getMinRequiredArguments () < tpl->size()) {
3836 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3841 if (!ctdWithDefaultArgs) {
3842 Error(
"KeepNParams",
"Not found template default arguments\n");
3843 normalizedType=originalNormalizedType;
3847 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3848 const TemplateParameterList& tPars = *tParsPtr;
3849 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3853 if (theTemplateName.isNull()) {
3854 normalizedType=originalNormalizedType;
3858 const TemplateSpecializationType* normalizedTst =
3859 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3860 if (!normalizedTst) {
3861 normalizedType=originalNormalizedType;
3865 const clang::ClassTemplateSpecializationDecl* TSTdecl
3866 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3874 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3876 const int nArgs = tArgs.size();
3877 const int nNormArgs = normalizedTst->getNumArgs();
3879 bool mightHaveChanged =
false;
3882 for (
int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
3883 const NamedDecl* tParPtr = tPars.getParam(formal);
3885 Error(
"KeepNParams",
"The parameter number %s is null.\n", formal);
3892 if (formal == nNormArgs || inst == nNormArgs)
break;
3894 const TemplateArgument& tArg = tArgs.get(formal);
3895 TemplateArgument normTArg(normalizedTst->getArgs()[inst]);
3898 if (isStdDropDefault) shouldKeepArg =
false;
3907 if ( tParPtr->isTemplateParameterPack() ) {
3912 for( ; inst != nNormArgs; ++inst) {
3913 normTArg = normalizedTst->getArgs()[inst];
3915 argsToKeep.push_back(normTArg);
3921 argsToKeep.push_back(normTArg);
3924 if (!isStdDropDefault) {
3926 mightHaveChanged =
true;
3936 auto argKind = tArg.getKind();
3939 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3940 }
else if (argKind == clang::TemplateArgument::Integral){
3945 argsToKeep.push_back(normTArg);
3947 mightHaveChanged =
true;
3953 if (!prefix_changed && !mightHaveChanged) {
3954 normalizedType = originalNormalizedType;
3959 if (mightHaveChanged) {
3960 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3961 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3963 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3964 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3970 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3971 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3985 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3988 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3989 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt,
type, normCtxt.
GetConfig(),
true );
3997 return normalizedType;
4011 if (
type.isNull()) {
4018 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
4019 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
4020 policy.SuppressTagKeyword =
true;
4021 policy.SuppressScope =
true;
4022 policy.AnonymousTagLocations =
false;
4027 std::string normalizedNameStep1;
4030 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
4031 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
4041 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
4042 norm_name.erase(0,2);
4050 const clang::TypeDecl* typeDecl,
4051 const cling::Interpreter &interpreter)
4054 const clang::Sema &sema = interpreter.getSema();
4055 clang::ASTContext& astCtxt = sema.getASTContext();
4056 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
4065std::pair<std::string,clang::QualType>
4067 const cling::Interpreter &interpreter,
4071 std::string thisTypeName;
4075 if (!hasChanged)
return std::make_pair(thisTypeName,thisType);
4079 "Name changed from %s to %s\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
4082 auto& lookupHelper = interpreter.getLookupHelper();
4085 lookupHelper.findScope(thisTypeNameForIO,
4086 cling::LookupHelper::DiagSetting::NoDiagnostics,
4090 if (!typePtrForIO) {
4092 "Type not found: %s.",thisTypeNameForIO.c_str());
4095 clang::QualType typeForIO(typePtrForIO,0);
4098 if (!typeForIO->isRecordType()) {
4099 return std::make_pair(thisTypeNameForIO,typeForIO);
4102 auto thisDeclForIO = typeForIO->getAsCXXRecordDecl();
4103 if (!thisDeclForIO) {
4105 "The type for IO corresponding to %s is %s and it could not be found in the AST as class.\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
4106 return std::make_pair(thisTypeName,thisType);
4109 return std::make_pair(thisTypeNameForIO,typeForIO);
4115 const cling::Interpreter &interpreter,
4127 std::string dictFileName(moduleName);
4128 dictFileName +=
"_rdict.pcm";
4129 return dictFileName;
4133 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4159 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4160 clang::SourceLocation sourceLocation = decl.getEndLoc();
4163 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
4171 if (!decl.hasOwningModule() && sourceManager.isLoadedSourceLocation(sourceLocation)) {
4177 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4181 bool skipToSemi =
true;
4182 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4183 if (FD->isImplicit()) {
4187 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4191 }
else if (FD->doesThisDeclarationHaveABody()) {
4194 assert((decl.getEndLoc() != sourceLocation || *commentStart ==
'}'
4196 &&
"Expected macro or end of body at '}'");
4197 if (*commentStart) ++commentStart;
4200 while (*commentStart && isspace(*commentStart)
4201 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4204 if (*commentStart ==
';') ++commentStart;
4208 }
else if (
const clang::EnumConstantDecl* ECD
4209 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4211 if (ECD->getNextDeclInContext())
4212 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4220 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4222 if (*commentStart ==
';') ++commentStart;
4226 while ( *commentStart && isspace(*commentStart)
4227 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4231 if (commentStart[0] !=
'/' ||
4232 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4242 unsigned int skipChars = 2;
4243 if (commentStart[0] ==
'/' &&
4244 commentStart[1] ==
'/' &&
4245 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4246 commentStart[3] ==
'<') {
4248 }
else if (commentStart[0] ==
'/' &&
4249 commentStart[1] ==
'*' &&
4250 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4251 commentStart[3] ==
'<') {
4255 commentStart += skipChars;
4258 while ( *commentStart && isspace(*commentStart)
4259 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4262 const char* commentEnd = commentStart;
4264 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4270 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4276 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4277 *loc = sourceLocation.getLocWithOffset(
offset - 1);
4280 return llvm::StringRef(commentStart, commentEnd - commentStart);
4288 if (!decl)
return false;
4290 auto& sema = interpreter.getCI()->getSema();
4291 auto maybeMacroLoc = decl->getLocation();
4293 if (!maybeMacroLoc.isMacroID())
return false;
4295 static const std::vector<std::string> signatures =
4296 {
"ClassDef",
"ClassDefOverride",
"ClassDefNV",
"ClassDefInline",
"ClassDefInlineOverride",
"ClassDefInlineNV" };
4298 for (
auto &
name : signatures)
4299 if (sema.findMacroSpelling(maybeMacroLoc,
name))
4313 clang::SourceLocation *loc,
4314 const cling::Interpreter &interpreter)
4316 using namespace clang;
4318 const Decl* DeclFileLineDecl
4319 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4320 cling::LookupHelper::NoDiagnostics);
4324 SourceLocation commentSLoc;
4333 return llvm::StringRef();
4345 if (rawtype->isElaboratedTypeSpecifier() ) {
4346 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4348 if (rawtype->isArrayType()) {
4349 rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
4351 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4353 clang::QualType pointee;
4354 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4356 rawtype = pointee.getTypePtr();
4358 if (rawtype->isElaboratedTypeSpecifier() ) {
4359 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4361 if (rawtype->isArrayType()) {
4362 rawtype = rawtype->getBaseElementTypeUnsafe ();
4366 if (rawtype->isArrayType()) {
4367 rawtype = rawtype->getBaseElementTypeUnsafe ();
4388 static const char *names[] =
4389 {
"shared_ptr",
"__shared_ptr",
4390 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4391 llvm::StringRef clname(cl.getName());
4392 for(
auto &&
name : names) {
4393 if (clname ==
name)
return true;
4403 const clang::CXXRecordDecl ¤tCl)
4406 if (&cl == ¤tCl)
return true;
4408 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4411 if (NULL == previous){
4430 const clang::CXXRecordDecl *thisDecl =
4431 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4435 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4440 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4466 auto *nsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext());
4467 if (cl.getName() !=
"RVec" || nsDecl ==
nullptr || nsDecl->getName() !=
"VecOps")
4470 auto *parentNsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext()->getParent());
4471 if (parentNsDecl ==
nullptr || parentNsDecl->getName() !=
"ROOT")
4479 using namespace clang;
4480 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4481 bool VisitTypedefType(
const TypedefType* TD) {
4484 bool VisitArrayType(
const ArrayType* AT) {
4485 return Visit(AT->getElementType().getTypePtr());
4487 bool VisitDecltypeType(
const DecltypeType* DT) {
4488 return Visit(DT->getUnderlyingType().getTypePtr());
4490 bool VisitPointerType(
const PointerType* PT) {
4491 return Visit(PT->getPointeeType().getTypePtr());
4493 bool VisitReferenceType(
const ReferenceType* RT) {
4494 return Visit(RT->getPointeeType().getTypePtr());
4496 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4497 return Visit(STST->getReplacementType().getTypePtr());
4499 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4500 for (
int I = 0,
N = TST->getNumArgs();
I <
N; ++
I) {
4501 const TemplateArgument&
TA = TST->getArg(
I);
4503 && Visit(
TA.getAsType().getTypePtr()))
4508 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4511 bool VisitTypeOfType(
const TypeOfType* TOT) {
4512 return TOT->getUnderlyingType().getTypePtr();
4514 bool VisitElaboratedType(
const ElaboratedType* ET) {
4515 NestedNameSpecifier* NNS = ET->getQualifier();
4517 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4518 if (Visit(NNS->getAsType()))
4521 NNS = NNS->getPrefix();
4523 return Visit(ET->getNamedType().getTypePtr());
4544 using namespace llvm;
4545 using namespace clang;
4546 const clang::ASTContext &Ctxt =
instance->getAsCXXRecordDecl()->getASTContext();
4549 const clang::ElaboratedType* etype
4550 = llvm::dyn_cast<clang::ElaboratedType>(
input.getTypePtr());
4554 clang::Qualifiers scope_qualifiers =
input.getLocalQualifiers();
4555 assert(
instance->getAsCXXRecordDecl()!=0 &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4557 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),
instance);
4560 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4561 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4565 QualType QT =
input;
4569 if (isa<clang::PointerType>(QT.getTypePtr())) {
4571 Qualifiers quals = QT.getQualifiers();
4574 if (nQT == QT->getPointeeType())
return QT;
4576 QT = Ctxt.getPointerType(nQT);
4578 QT = Ctxt.getQualifiedType(QT, quals);
4584 if (isa<ReferenceType>(QT.getTypePtr())) {
4586 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4587 Qualifiers quals = QT.getQualifiers();
4590 if (nQT == QT->getPointeeType())
return QT;
4594 QT = Ctxt.getLValueReferenceType(nQT);
4596 QT = Ctxt.getRValueReferenceType(nQT);
4598 QT = Ctxt.getQualifiedType(QT, quals);
4604 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4606 Qualifiers quals = QT.getQualifiers();
4608 if (
const auto arr = dyn_cast<ConstantArrayType>(QT.getTypePtr())) {
4611 if (newQT == arr->getElementType())
return QT;
4612 QT = Ctxt.getConstantArrayType (newQT,
4614 arr->getSizeModifier(),
4615 arr->getIndexTypeCVRQualifiers());
4617 }
else if (
const auto arr = dyn_cast<DependentSizedArrayType>(QT.getTypePtr())) {
4620 if (newQT == QT)
return QT;
4621 QT = Ctxt.getDependentSizedArrayType (newQT,
4623 arr->getSizeModifier(),
4624 arr->getIndexTypeCVRQualifiers(),
4625 arr->getBracketsRange());
4627 }
else if (
const auto arr = dyn_cast<IncompleteArrayType>(QT.getTypePtr())) {
4630 if (newQT == arr->getElementType())
return QT;
4631 QT = Ctxt.getIncompleteArrayType (newQT,
4632 arr->getSizeModifier(),
4633 arr->getIndexTypeCVRQualifiers());
4635 }
else if (
const auto arr = dyn_cast<VariableArrayType>(QT.getTypePtr())) {
4638 if (newQT == arr->getElementType())
return QT;
4639 QT = Ctxt.getVariableArrayType (newQT,
4641 arr->getSizeModifier(),
4642 arr->getIndexTypeCVRQualifiers(),
4643 arr->getBracketsRange());
4647 QT = Ctxt.getQualifiedType(QT, quals);
4652 etype = llvm::dyn_cast<clang::ElaboratedType>(
instance);
4654 instance = etype->getNamedType().getTypePtr();
4658 const clang::TemplateSpecializationType* TST
4659 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
instance);
4661 if (!TST)
return input;
4663 const clang::ClassTemplateSpecializationDecl* TSTdecl
4664 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(
instance->getAsCXXRecordDecl());
4666 if (!TSTdecl)
return input;
4668 const clang::SubstTemplateTypeParmType *substType
4669 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(
input.getTypePtr());
4673 const clang::ClassTemplateDecl *replacedCtxt = 0;
4675 const clang::DeclContext *replacedDeclCtxt = substType->getReplacedParameter()->getDecl()->getDeclContext();
4676 const clang::CXXRecordDecl *decl = llvm::dyn_cast<clang::CXXRecordDecl>(replacedDeclCtxt);
4677 unsigned int index = substType->getReplacedParameter()->getIndex();
4680 if (decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4681 const clang::ClassTemplatePartialSpecializationDecl *spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(decl);
4683 unsigned int depth = substType->getReplacedParameter()->getDepth();
4685 const TemplateArgument *instanceArgs = spec->getTemplateArgs().data();
4686 unsigned int instanceNArgs = spec->getTemplateArgs().size();
4690 for(
unsigned int A = 0;
A < instanceNArgs; ++
A) {
4692 clang::QualType argQualType = instanceArgs[
A].getAsType();
4694 const clang::TemplateTypeParmType *replacementType;
4696 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(argQualType);
4698 if (!replacementType) {
4699 const clang::SubstTemplateTypeParmType *argType
4700 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(argQualType);
4702 clang::QualType replacementQT = argType->getReplacementType();
4703 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(replacementQT);
4706 if (replacementType &&
4707 depth == replacementType->getDepth() &&
4708 index == replacementType->getIndex() )
4715 replacedCtxt = spec->getSpecializedTemplate();
4717 replacedCtxt = decl->getDescribedClassTemplate();
4719 }
else if (
auto const declguide = llvm::dyn_cast<clang::CXXDeductionGuideDecl>(replacedDeclCtxt)) {
4720 replacedCtxt = llvm::dyn_cast<clang::ClassTemplateDecl>(declguide->getDeducedTemplate());
4721 }
else if (
auto const ctdecl = llvm::dyn_cast<clang::ClassTemplateDecl>(replacedDeclCtxt)) {
4722 replacedCtxt = ctdecl;
4724 std::string astDump;
4725 llvm::raw_string_ostream ostream(astDump);
4728 ROOT::TMetaUtils::Warning(
"ReSubstTemplateArg",
"Unexpected type of declaration context for template parameter: %s.\n\tThe responsible class is:\n\t%s\n",
4729 replacedDeclCtxt->getDeclKindName(), astDump.c_str());
4730 replacedCtxt =
nullptr;
4733 if ((replacedCtxt && replacedCtxt->getCanonicalDecl() == TSTdecl->getSpecializedTemplate()->getCanonicalDecl())
4735 substType->getReplacedParameter()->getDecl()
4736 == TSTdecl->getSpecializedTemplate ()->getTemplateParameters()->getParam(
index))
4738 if (
index >= TST->getNumArgs() ) {
4745 return TST->getArg(
index).getAsType();
4750 const clang::TemplateSpecializationType* inputTST
4751 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
input.getTypePtr());
4752 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4755 bool mightHaveChanged =
false;
4756 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4757 for(clang::TemplateSpecializationType::iterator
I = inputTST->begin(),
E = inputTST->end();
4760 desArgs.push_back(*
I);
4764 clang::QualType SubTy =
I->getAsType();
4766 if (llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4767 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4769 mightHaveChanged = SubTy != newSubTy;
4770 if (!newSubTy.isNull()) {
4771 desArgs.push_back(clang::TemplateArgument(newSubTy));
4774 desArgs.push_back(*
I);
4778 if (mightHaveChanged) {
4779 clang::Qualifiers qualifiers =
input.getLocalQualifiers();
4780 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4782 inputTST->getCanonicalTypeInternal());
4783 input = astCtxt.getQualifiedType(
input, qualifiers);
4795 if ( nArgsToRemove == 0 ||
name ==
"")
4802 unsigned int nArgsRemoved=0;
4803 unsigned int nBraces=0;
4805 while (nArgsRemoved!=nArgsToRemove && cur<
length){
4807 if (
c ==
'<') nBraces++;
4808 if (
c ==
'>') nBraces--;
4809 if (
c ==
',' && nBraces==1 ) nArgsRemoved++;
4823 static const char *stls[] =
4824 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4825 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
"RVec", 0};
4839 for(
int k=1;stls[k];k++) {
if (
type.equals(stls[k]))
return values[k];}
4850 TND = TND->getMostRecentDecl();
4851 while (TND && !(TND->hasAttrs()))
4852 TND = TND->getPreviousDecl();
4864 TD = TD->getMostRecentDecl();
4865 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4866 TD = TD->getPreviousDecl();
4875 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4877 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4878 if (!enclosingNamespaceDeclCtxt)
return;
4880 const clang::NamespaceDecl* enclosingNamespace =
4881 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4882 if (!enclosingNamespace)
return;
4884 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4885 enclosingNamespace->isInline()));
4895 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4897 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4900 if (!enclosingNamespaceDeclCtxt) {
4906 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4907 if (!enclosingNamespace)
return;
4910 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4911 enclosingNamespace->isInline()));
4922 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4924 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4925 if (!enclosingDeclCtxt)
return nullptr;
4927 unsigned int scopeType;
4929 if (
auto enclosingNamespacePtr =
4930 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4931 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4932 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4936 if (
auto enclosingClassPtr =
4937 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4938 return enclosingClassPtr;
4950 std::string::size_type beginVar = 0;
4951 std::string::size_type endVar = 0;
4952 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4953 && beginVar + 1 < txt.length()) {
4954 std::string::size_type beginVarName = beginVar + 1;
4955 std::string::size_type endVarName = std::string::npos;
4956 if (txt[beginVarName] ==
'(') {
4958 endVarName = txt.find(
')', beginVarName);
4960 if (endVarName == std::string::npos) {
4962 varname, txt.c_str() + beginVar);
4965 endVar = endVarName + 1;
4968 beginVarName = beginVar + 1;
4969 endVarName = beginVarName;
4970 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
4972 endVar = endVarName;
4975 const char* val = getenv(txt.substr(beginVarName,
4976 endVarName - beginVarName).c_str());
4979 txt.replace(beginVar, endVar - beginVar, val);
4980 int lenval = strlen(val);
4981 int delta = lenval - (endVar - beginVar);
4985 beginVar = endVar + 1;
4997 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
5001 std::istringstream envInclPathsStream(envInclPath);
5002 std::string inclPath;
5003 while (std::getline(envInclPathsStream, inclPath,
':')) {
5006 if (!inclPath.empty()) {
5007 clingArgs.push_back(
"-I");
5008 clingArgs.push_back(inclPath);
5019 size_t start_pos = 0;
5024 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
5025 str.replace(start_pos, from.length(), to);
5026 start_pos += to.length();
5027 if (recurse) changed =
true;
5043 if (theString.size() < theSubstring.size())
return false;
5044 const unsigned int theSubstringSize = theSubstring.size();
5045 return 0 == theString.compare(theString.size() - theSubstringSize,
5054 if (theString.size() < theSubstring.size())
return false;
5055 const unsigned int theSubstringSize = theSubstring.size();
5056 return 0 == theString.compare(0,
5074 size_t linkdeflen = 9;
5076 if (0 == strncasecmp(
filename + (
len - linkdeflen),
"linkdef", linkdeflen - 2)
5105 cling::Interpreter::IgnoreFilesFunc_t ignoreFiles,
5106 const cling::Interpreter &interp,
5109 clang::Sema &sema = interp.getSema();
5110 cling::Transaction theTransaction(sema);
5111 std::set<clang::Decl *> addedDecls;
5112 for (
auto decl : decls) {
5114 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
5115 theTransaction.append(ncDecl);
5117 std::string newFwdDecl;
5118 llvm::raw_string_ostream llvmOstr(newFwdDecl);
5120 std::string locallogs;
5121 llvm::raw_string_ostream llvmLogStr(locallogs);
5122 interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr,
true,
5123 logs ? &llvmLogStr :
nullptr, ignoreFiles);
5127 logs->swap(locallogs);
5139 std::string& defString)
5151 std::string& defString)
5153 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5156 if (rcdPtr)
return rcdPtr;
5159 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5161 std::string scopeName;
5162 std::string scopeContent;
5163 unsigned int scopeIndex;
5164 for (
auto const & encScope : enclosingNamespaces){
5165 scopeIndex = encScope.second;
5166 scopeName = encScope.first;
5167 scopeContent =
" { " + defString +
" }";
5168 defString = scopeType[scopeIndex] +
5190 const clang::TemplateParameterList& tmplParamList,
5191 const cling::Interpreter& interpreter)
5194 for (
auto prmIt = tmplParamList.begin();
5195 prmIt != tmplParamList.end(); prmIt++){
5197 if (prmIt != tmplParamList.begin())
5198 templateArgs +=
", ";
5200 auto nDecl = *prmIt;
5201 std::string typeName;
5204 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5205 typeName =
"typename ";
5206 if (nDecl->isParameterPack())
5208 typeName += (*prmIt)->getNameAsString();
5211 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5212 auto theType = nttpd->getType();
5215 if (theType.getAsString().find(
"enum") != std::string::npos){
5216 std::string astDump;
5217 llvm::raw_string_ostream ostream(astDump);
5218 nttpd->dump(ostream);
5220 ROOT::TMetaUtils::Warning(0,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5229 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5232 std::string astDump;
5233 llvm::raw_string_ostream ostream(astDump);
5234 ttpd->dump(ostream);
5236 ROOT::TMetaUtils::Error(0,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5241 templateArgs += typeName;
5252 const cling::Interpreter& interpreter,
5253 std::string& defString)
5255 std::string templatePrefixString;
5256 auto tmplParamList= templDecl.getTemplateParameters();
5257 if (!tmplParamList){
5259 "Cannot extract template parameter list for %s",
5260 templDecl.getNameAsString().c_str());
5267 "Problems with arguments for forward declaration of class %s\n",
5268 templDecl.getNameAsString().c_str());
5271 templatePrefixString =
"template " + templatePrefixString +
" ";
5273 defString = templatePrefixString +
"class ";
5274 if (templDecl.isParameterPack())
5275 defString +=
"... ";
5276 defString += templDecl.getNameAsString();
5277 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5291 std::string& argFwdDecl,
5292 const cling::Interpreter& interpreter,
5293 bool acceptStl=
false)
5301 auto argQualType = arg.getAsType();
5304 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5306 auto argTypePtr = argQualType.getTypePtr();
5309 if (llvm::isa<clang::EnumType>(argTypePtr)){
5314 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5319 if (
auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr)) {
5324 if (
auto argRecTypePtr = llvm::dyn_cast<clang::RecordType>(argTypePtr)){
5326 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5339 const cling::Interpreter& interpreter,
5340 std::string& defString,
5341 const std::string &normalizedName)
5345 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)) {
5346 if (
const auto *specDef = tmplSpecDeclPtr->getDefinition()) {
5347 if (specDef->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization)
5351 std::cout <<
" Forward declaring template spec " << normalizedName <<
":\n";
5352 for (
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()) {
5353 std::string argFwdDecl;
5356 std::cout <<
" o Template argument ";
5358 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5360 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5367 defString += argFwdDecl +
'\n';
5369 defString +=
"template <> class " + normalizedName +
';';
5383 const cling::Interpreter& interpreter,
5384 std::string& defString,
5392 if (!recordDecl.getIdentifier())
5396 std::string argsFwdDecl;
5398 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5399 std::string argFwdDecl;
5401 std::cout <<
"Class " << recordDecl.getNameAsString()
5402 <<
" is a template specialisation. Treating its arguments.\n";
5403 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5406 std::cout <<
" o Template argument ";
5408 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5410 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5417 argsFwdDecl+=argFwdDecl;
5421 defString=argsFwdDecl;
5426 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5429 defString = argsFwdDecl +
"\n" + defString;
5434 defString =
"class " + recordDecl.getNameAsString() +
";";
5435 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5443 defString = argsFwdDecl +
"\n" + defString;
5454 const cling::Interpreter& interpreter,
5455 std::string& fwdDeclString,
5456 std::unordered_set<std::string>* fwdDeclSetPtr)
5458 std::string buffer = tdnDecl.getNameAsString();
5459 std::string underlyingName;
5460 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5461 if (
const clang::TagType* TT
5462 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5463 if (clang::NamedDecl* ND = TT->getDecl()) {
5464 if (!ND->getIdentifier()) {
5478 if (underlyingName.find(
">::") != std::string::npos)
5481 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5493 auto& ctxt = tdnDecl.getASTContext();
5494 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5496 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5497 std::string tdnFwdDecl;
5498 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5503 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5504 fwdDeclString+=tdnFwdDecl;
5505 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5506 std::string classFwdDecl;
5508 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: "
5509 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5518 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5519 fwdDeclString+=classFwdDecl;
5522 fwdDeclString+=buffer;
5534 std::string& valAsString,
5535 const clang::PrintingPolicy& ppolicy)
5537 auto defArgExprPtr = par.getDefaultArg();
5538 auto& ctxt = par.getASTContext();
5539 if(!defArgExprPtr->isEvaluatable(ctxt)){
5543 auto defArgType = par.getType();