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,
164 const clang::Type *instance)
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());
186static bool IsTypeInt(
const clang::Type *
type)
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,
400 const clang::Type *requestedType,
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");
430 const clang::Type *requestedType,
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);
667 if (
const clang::Type* T = toSkip.getTypePtr()) {
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 *
740 bool ,
const clang::Type** resultType)
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
843 const clang::Type &ti( * qti.getTypePtr() );
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 " || qual_name ==
"(unnamed" ) {
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();
1584 if (
I->getKind() == clang::TemplateArgument::Type) {
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().str();
1634 size_t substrFound (attributeStr.find(propNames::separator));
1635 if (substrFound==std::string::npos) {
1639 size_t EndPart1 = attributeStr.find_first_of(propNames::separator) ;
1640 attrName = attributeStr.substr(0, EndPart1);
1641 const int separatorLength(propNames::separator.
size());
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.str();
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,
"::");
1730 bool isStd = TMetaUtils::IsStdClass(*decl);
1731 const cling::LookupHelper& lh = interp.getLookupHelper();
1732 bool isString = TMetaUtils::IsOfType(*decl,
"std::string",lh);
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" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2009 finalString <<
"\n" <<
" instance.AdoptAlternate(::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(static_cast<" << csymbol <<
"*>(nullptr));\n }" <<
"\n";
2041 finalString <<
" // Static variable to force the class initialization" <<
"\n";
2045 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal(static_cast<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(static_cast<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) {
2115 TMetaUtils::Error(0,
"Cannot convert field declaration to clang::NamedDecl");
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";
2131 if (attrName == propNames::comment ||
2132 attrName == propNames::iotype ||
2133 attrName == propNames::ioname )
continue;
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 (static_cast<" << classname.c_str() <<
"*>(p));" <<
"\n" <<
" }" <<
"\n" <<
" static void deleteArray_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" delete [] (static_cast<" << classname.c_str() <<
"*>(p));" <<
"\n" <<
" }" <<
"\n" <<
" static void destruct_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" typedef " << classname.c_str() <<
" current_t;" <<
"\n" <<
" (static_cast<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 if (
auto RetRes = RetExpr->getIntegerConstantExpr(funcCV->getASTContext())) {
2594 if (RetRes->isSigned())
2595 return res_t{
true, (
Version_t)RetRes->getSExtValue()};
2596 return res_t{
true, (
Version_t)RetRes->getZExtValue()};
2598 return res_t{
false, -1};
2614 clang::QualType
type =
m.getType();
2617 if (decl)
return TMetaUtils::IsSTLCont(*decl);
2626 clang::QualType
type = base.getType();
2629 if (decl)
return TMetaUtils::IsSTLCont(*decl);
2639 const std::function<
void(
const clang::Module::Header &)> &closure,
2640 bool includeDirectlyUsedModules)
2649 const std::size_t publicHeaderIndex = 4;
2652 const std::size_t maxArrayLength = ((
sizeof module.Headers) / (
sizeof *module.Headers));
2653 static_assert(publicHeaderIndex + 1 == maxArrayLength,
2654 "'Headers' has changed it's size, we need to update publicHeaderIndex");
2659 llvm::SetVector<const clang::Module *> modules;
2660 modules.insert(&module);
2661 for (
size_t i = 0; i < modules.size(); ++i) {
2662 const clang::Module *M = modules[i];
2663 for (
const clang::Module *subModule : M->submodules())
2664 modules.insert(subModule);
2667 for (
const clang::Module *
m : modules) {
2668 if (includeDirectlyUsedModules) {
2669 for (clang::Module *used :
m->DirectUses) {
2674 for (std::size_t i = 0; i < publicHeaderIndex; i++) {
2675 auto &headerList =
m->Headers[i];
2676 for (
const clang::Module::Header &moduleHeader : headerList) {
2677 closure(moduleHeader);
2691 static char t[4096];
2692 static const char* constwd =
"const ";
2693 static const char* constwdend =
"const";
2698 for (s=typeDesc;*s;s++) {
2701 if (lev==0 && *s==
'*')
continue;
2702 if (lev==0 && (strncmp(constwd,s,strlen(constwd))==0
2703 ||strcmp(constwdend,s)==0 ) ) {
2704 s+=strlen(constwd)-1;
2707 if (lev==0 && *s==
' ' && *(s+1)!=
'*') {
p = t;
continue;}
2708 if (
p - t > (
long)
sizeof(t)) {
2709 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2722 const cling::Interpreter& interp)
2727 if (!comment.empty() && comment[0] ==
'!')
2730 clang::QualType
type =
m.getType();
2732 if (
type->isReferenceType()) {
2737 std::string mTypeName =
type.getAsString(
m.getASTContext().getPrintingPolicy());
2738 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2741 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2749 const clang::Type *rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
2751 if (rawtype->isPointerType()) {
2753 clang::QualType pointee;
2754 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2756 rawtype = pointee.getTypePtr();
2760 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2765 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2769 if (version > 0)
return true;
2782 const clang::Type *rawtype =
m.getType().getTypePtr();
2785 clang::QualType pointee;
2786 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2788 rawtype = pointee.getTypePtr();
2802 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2806 return rawtype->getAsCXXRecordDecl();
2815 const cling::Interpreter &interp,
2817 std::ostream& dictStream,
2819 bool isGenreflex=
false)
2821 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2823 if (!decl || !decl->isCompleteDefinition()) {
2827 std::string fullname;
2830 Internal::RStl::Instance().GenerateTClassFor(cl.
GetNormalizedName(), llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl()), interp, normCtxt);
2839 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2841 ROOT::TMetaUtils::Info(0,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2863 const cling::Interpreter &interpreter,
2866 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2868 clang::QualType originalType = instanceType;
2872 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2874 clang::Qualifiers quals = instanceType.getQualifiers();
2875 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2876 if (newPointee != instanceType->getPointeeType()) {
2877 instanceType = Ctx.getPointerType(newPointee);
2879 instanceType = Ctx.getQualifiedType(instanceType, quals);
2881 return instanceType;
2886 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2888 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2889 clang::Qualifiers quals = instanceType.getQualifiers();
2890 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2892 if (newPointee != instanceType->getPointeeType()) {
2895 instanceType = Ctx.getLValueReferenceType(newPointee);
2897 instanceType = Ctx.getRValueReferenceType(newPointee);
2899 instanceType = Ctx.getQualifiedType(instanceType, quals);
2901 return instanceType;
2905 bool prefix_changed =
false;
2906 clang::NestedNameSpecifier* prefix = 0;
2907 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2908 const clang::ElaboratedType* etype
2909 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2912 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2913 prefix_changed = prefix != etype->getQualifier();
2914 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2920 const clang::TemplateSpecializationType* TST
2921 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2923 const clang::ClassTemplateSpecializationDecl* TSTdecl
2924 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2936 bool mightHaveChanged =
false;
2937 if (TST && TSTdecl) {
2939 clang::Sema& S = interpreter.getCI()->getSema();
2940 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2941 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2942 clang::TemplateParameterList::iterator Param = Params->
begin();
2946 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2948 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2949 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2950 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2951 for(clang::TemplateSpecializationType::iterator
2952 I = TST->begin(), E = TST->end();
2954 I!=E ? ++
I : 0, ++Idecl, ++Param) {
2958 if (
I->getKind() == clang::TemplateArgument::Template) {
2959 clang::TemplateName templateName =
I->getAsTemplate();
2960 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2962 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2964 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2965 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2966 clang::NestedNameSpecifier* nns;
2968 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx, ns);
2969 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2970 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2973 desArgs.push_back(*
I);
2976 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, templateDecl) );
2977 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2978 mightHaveChanged =
true;
2984 if (
I->getKind() != clang::TemplateArgument::Type) {
2985 desArgs.push_back(*
I);
2989 clang::QualType SubTy =
I->getAsType();
2998 if (SubTy != newSubTy) {
2999 mightHaveChanged =
true;
3000 desArgs.push_back(clang::TemplateArgument(newSubTy));
3002 desArgs.push_back(*
I);
3005 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
3007 mightHaveChanged =
true;
3009 const clang::TemplateArgument& templateArg
3010 = TSTdecl->getTemplateArgs().get(Idecl);
3011 if (templateArg.getKind() != clang::TemplateArgument::Type) {
3012 desArgs.push_back(templateArg);
3015 clang::QualType SubTy = templateArg.getAsType();
3017 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3018 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
3020 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
3023 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
3024 clang::sema::HackForDefaultTemplateArg raii;
3025 bool HasDefaultArgs;
3026 clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
3035 if (ArgType.getArgument().isNull()
3036 || ArgType.getArgument().getKind() != clang::TemplateArgument::Type) {
3038 "Template parameter substitution failed for %s around %s\n",
3039 instanceType.getAsString().c_str(), SubTy.getAsString().c_str());
3042 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
3043 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
3046 desArgs.push_back(clang::TemplateArgument(SubTy));
3055 if (mightHaveChanged) {
3056 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
3058 TST->getCanonicalTypeInternal());
3062 if (!prefix_changed && !mightHaveChanged)
return originalType;
3064 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
3065 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
3067 return instanceType;
3087 llvm::StringRef title;
3090 if (clang::AnnotateAttr *A =
m.getAttr<clang::AnnotateAttr>())
3091 title = A->getAnnotation();
3103 if (errnum) *errnum =
VALID;
3105 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3106 size_t rightbracket = title.find(
']');
3107 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3109 std::string working;
3110 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
3117 size_t indexvarlen = indexvar.size();
3118 for ( i=0; i<indexvarlen; i++) {
3119 if (!isspace(indexvar[i])) {
3120 working += indexvar[i];
3125 const char *tokenlist =
"*+-";
3126 char *current =
const_cast<char*
>(working.c_str());
3127 current = strtok(current,tokenlist);
3129 while (current!=0) {
3131 if (isdigit(current[0])) {
3132 for(i=0;i<strlen(current);i++) {
3133 if (!isdigit(current[i])) {
3138 if (errstr) *errstr = current;
3139 if (errnum) *errnum =
NOT_INT;
3140 return llvm::StringRef();
3145 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext());
3146 const clang::FieldDecl *index1 =
nullptr;
3148 index1 = GetDataMemberFromAll(*parent_clxx, current );
3150 if ( IsFieldDeclInt(index1) ) {
3155 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3159 if ( field_iter->getNameAsString() ==
m.getNameAsString() ) {
3165 if (errstr) *errstr = current;
3166 if (errnum) *errnum =
NOT_DEF;
3167 return llvm::StringRef();
3169 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3177 if (errstr) *errstr = current;
3178 if (errnum) *errnum =
NOT_INT;
3179 return llvm::StringRef();
3186 clang::Sema& SemaR =
const_cast<cling::Interpreter&
>(interp).getSema();
3187 index1 = GetDataMemberFromAllParents(SemaR, *parent_clxx, current);
3190 if ( IsFieldDeclInt(index1) ) {
3197 if (errnum) *errnum =
NOT_INT;
3198 if (errstr) *errstr = current;
3202 if (errnum) *errnum =
NOT_INT;
3203 if (errstr) *errstr = current;
3204 return llvm::StringRef();
3206 if ( found && (index1->getAccess() == clang::AS_private) ) {
3209 if (errstr) *errstr = current;
3211 return llvm::StringRef();
3218 if (errstr) *errstr = indexvar;
3219 if (errnum) *errnum =
UNKNOWN;
3220 return llvm::StringRef();
3225 current = strtok(0,tokenlist);
3241 while((
c = in[i++])) {
3242 const char *repl =
nullptr;
3244 case '+': repl =
"pL";
break;
3245 case '-': repl =
"mI";
break;
3246 case '*': repl =
"mU";
break;
3247 case '/': repl =
"dI";
break;
3248 case '&': repl =
"aN";
break;
3249 case '%': repl =
"pE";
break;
3250 case '|': repl =
"oR";
break;
3251 case '^': repl =
"hA";
break;
3252 case '>': repl =
"gR";
break;
3253 case '<': repl =
"lE";
break;
3254 case '=': repl =
"eQ";
break;
3255 case '~': repl =
"wA";
break;
3256 case '.': repl =
"dO";
break;
3257 case '(': repl =
"oP";
break;
3258 case ')': repl =
"cP";
break;
3259 case '[': repl =
"oB";
break;
3260 case ']': repl =
"cB";
break;
3261 case '!': repl =
"nO";
break;
3262 case ',': repl =
"cO";
break;
3263 case '$': repl =
"dA";
break;
3264 case ' ': repl =
"sP";
break;
3265 case ':': repl =
"cL";
break;
3266 case '"': repl =
"dQ";
break;
3267 case '@': repl =
"aT";
break;
3268 case '\'': repl =
"sQ";
break;
3269 case '\\': repl =
"fI";
break;
3278 auto firstNonNumber = out.find_first_not_of(
"0123456789");
3279 if (firstNonNumber != std::string::npos)
3280 out.replace(0,firstNonNumber,
"");
3283static clang::SourceLocation
3285 clang::SourceLocation sourceLoc) {
3287 if (!sourceLoc.isFileID()) {
3288 return sourceManager.getExpansionRange(sourceLoc).getEnd();
3297 const cling::Interpreter& interp)
3327 using namespace clang;
3328 SourceLocation headerLoc = decl.getLocation();
3330 static const char invalidFilename[] =
"";
3331 if (!headerLoc.isValid())
return invalidFilename;
3333 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3335 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3337 FileID headerFID = sourceManager.getFileID(headerLoc);
3338 SourceLocation includeLoc
3340 sourceManager.getIncludeLoc(headerFID));
3342 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3343 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3344 const DirectoryLookup *foundDir = 0;
3347 assert(headerFE &&
"Couldn't find FileEntry from FID!");
3349 = HdrSearch.LookupFile(llvm::sys::path::filename(headerFE->getName()),
3352 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3360 headerFID = sourceManager.getFileID(includeLoc);
3361 headerFE = sourceManager.getFileEntryForID(headerFID);
3366 if (interp.getCI()->getLangOpts().Modules && !headerFE) {
3367 assert(decl.isFirstDecl() &&
"Couldn't trace back include from a decl"
3368 " that is not from an AST file");
3369 assert(StringRef(includeLoc.printToString(sourceManager)).startswith(
"<module-includes>"));
3373 sourceManager.getIncludeLoc(headerFID));
3376 if (!headerFE)
return invalidFilename;
3378 llvm::SmallString<256> headerFileName(headerFE->getName());
3381 llvm::sys::path::remove_dots(headerFileName,
true);
3392 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3393 llvm::Optional<clang::FileEntryRef> FELong;
3395 for (llvm::sys::path::const_iterator
3396 IDir = llvm::sys::path::begin(headerFileName),
3397 EDir = llvm::sys::path::end(headerFileName);
3398 !FELong && IDir != EDir; ++IDir) {
3404 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3405 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3406 assert(trailingPart.data() + trailingPart.size()
3407 == headerFileName.data() + headerFileName.size()
3408 &&
"Mismatched partitioning of file name!");
3409 const DirectoryLookup* FoundDir = 0;
3410 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3412 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3420 return invalidFilename;
3424 for (llvm::sys::path::reverse_iterator
3425 IDir = llvm::sys::path::rbegin(headerFileName),
3426 EDir = llvm::sys::path::rend(headerFileName);
3427 IDir != EDir; ++IDir) {
3428 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3429 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3430 assert(trailingPart.data() + trailingPart.size()
3431 == headerFileName.data() + headerFileName.size()
3432 &&
"Mismatched partitioning of file name!");
3433 const DirectoryLookup* FoundDir = 0;
3436 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3438 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3441 0,
nullptr ) == FELong) {
3442 return trailingPart.str();
3446 return invalidFilename;
3452 const clang::QualType &qtype,
3453 const clang::ASTContext &astContext)
3455 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3464 const clang::QualType &qtype,
3465 const cling::Interpreter &interpreter)
3470 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3474 interpreter.getCI()->getASTContext());
3482 clang::ClassTemplateDecl*& ctd,
3483 clang::ClassTemplateSpecializationDecl*& ctsd)
3485 using namespace clang;
3486 const Type* theType = qt.getTypePtr();
3493 if (theType->isPointerType()) {
3497 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3498 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3500 ctd = ctsd->getSpecializedTemplate();
3505 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3510 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3512 ctd = ctsd->getSpecializedTemplate();
3527 using namespace clang;
3528 ClassTemplateSpecializationDecl* ctsd;
3529 ClassTemplateDecl* ctd;
3543 using namespace clang;
3544 TemplateName theTemplateName;
3546 const Type* theType = qt.getTypePtr();
3548 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3549 theTemplateName = tst->getTemplateName();
3552 theTemplateName = TemplateName(ctd);
3555 return theTemplateName;
3561 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3562 const clang::NamedDecl& tPar,
3563 const cling::Interpreter& interp,
3567 using namespace clang;
3570 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3571 if (!ttpdPtr)
return false;
3572 if (!ttpdPtr->hasDefaultArgument())
return false;
3575 QualType tParQualType = ttpdPtr->getDefaultArgument();
3576 const QualType tArgQualType = tArg.getAsType();
3583 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3594 const clang::ElaboratedType* etype
3595 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3597 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3598 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3601 const TemplateSpecializationType* tst =
3602 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3607 ClassTemplateSpecializationDecl* TSTdecl
3608 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3613 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3616 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3619 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3624 TemplateArgument newArg = tArg;
3626 clang::Sema& S = interp.getCI()->getSema();
3627 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
3628 clang::sema::HackForDefaultTemplateArg raii;
3629 bool HasDefaultArgs;
3630 TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
3638 newArg = defTArgLoc.getArgument();
3639 if (newArg.isNull() ||
3640 newArg.getKind() != clang::TemplateArgument::Type) {
3642 "Template parameter substitution failed!");
3645 ClassTemplateSpecializationDecl* nTSTdecl
3646 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3649 isEqual = (nTSTdecl && nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl()) ||
3650 (tParQualType.getTypePtr() == newArg.getAsType().getTypePtr());
3662 const clang::NamedDecl& tPar)
3664 using namespace clang;
3665 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3666 if (!nttpdPtr)
return false;
3667 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3669 if (!nttpd.hasDefaultArgument())
3673 llvm::APSInt defaultValueAPSInt(64,
false);
3674 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3675 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3676 if (
auto Value = defArgExpr->getIntegerConstantExpr(astCtxt))
3677 defaultValueAPSInt = *
Value;
3680 const int value = tArg.getAsIntegral().getLimitedValue();
3683 return value == defaultValueAPSInt;
3693 using namespace clang;
3694 if (!nDecl)
return false;
3695 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3696 return ttpd->hasDefaultArgument();
3697 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3698 return nttpd->hasDefaultArgument();
3703static void KeepNParams(clang::QualType& normalizedType,
3704 const clang::QualType& vanillaType,
3705 const cling::Interpreter& interp,
3710 const clang::TemplateArgument &tArg,
3711 const cling::Interpreter& interp,
3713 const clang::ASTContext& astCtxt)
3716 using namespace clang;
3723 if (tArg.getKind() == clang::TemplateArgument::Type) {
3724 QualType thisNormQualType = normTArg.getAsType();
3725 QualType thisArgQualType = tArg.getAsType();
3730 normTArg = TemplateArgument(thisNormQualType);
3731 return (thisNormQualType != thisArgQualType);
3732 }
else if (normTArg.getKind() == clang::TemplateArgument::Pack) {
3733 assert( tArg.getKind() == clang::TemplateArgument::Pack );
3735 SmallVector<TemplateArgument, 2> desArgs;
3736 bool mightHaveChanged =
true;
3737 for (
auto I = normTArg.pack_begin(), E = normTArg.pack_end(),
3738 FI = tArg.pack_begin(), FE = tArg.pack_end();
3739 I != E && FI != FE; ++
I, ++FI)
3741 TemplateArgument pack_arg(*
I);
3743 desArgs.push_back(pack_arg);
3745 if (mightHaveChanged) {
3746 ASTContext &mutableCtx(
const_cast<ASTContext&
>(astCtxt) );
3747 normTArg = TemplateArgument::CreatePackCopy(mutableCtx, desArgs);
3749 return mightHaveChanged;
3760 const clang::QualType& vanillaType,
3761 const cling::Interpreter& interp,
3765 using namespace clang;
3769 ClassTemplateSpecializationDecl* ctsd;
3770 ClassTemplateDecl* ctd;
3771 if (! QualType2Template(vanillaType, ctd, ctsd)) return ;
3777 QualType originalNormalizedType = normalizedType;
3779 const ASTContext& astCtxt = ctsd->getASTContext();
3784 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3786 clang::Qualifiers quals = normalizedType.getQualifiers();
3787 auto valNormalizedType = normalizedType->getPointeeType();
3788 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3789 normalizedType = astCtxt.getPointerType(valNormalizedType);
3791 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3797 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3799 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3800 clang::Qualifiers quals = normalizedType.getQualifiers();
3801 auto valNormType = normalizedType->getPointeeType();
3802 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3806 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3808 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3810 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3815 bool prefix_changed =
false;
3816 clang::NestedNameSpecifier* prefix =
nullptr;
3817 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3818 const clang::ElaboratedType* etype
3819 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3823 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3824 prefix_changed = prefix != etype->getQualifier();
3825 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3831 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3832 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3833 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3834 if (tpl->getMinRequiredArguments () < tpl->size()) {
3835 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3840 if (!ctdWithDefaultArgs) {
3841 Error(
"KeepNParams",
"Not found template default arguments\n");
3842 normalizedType=originalNormalizedType;
3846 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3847 const TemplateParameterList& tPars = *tParsPtr;
3848 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3851 TemplateName theTemplateName = ExtractTemplateNameFromQualType(normalizedType);
3852 if (theTemplateName.isNull()) {
3853 normalizedType=originalNormalizedType;
3857 const TemplateSpecializationType* normalizedTst =
3858 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3859 if (!normalizedTst) {
3860 normalizedType=originalNormalizedType;
3864 const clang::ClassTemplateSpecializationDecl* TSTdecl
3865 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3866 bool isStdDropDefault = TSTdecl && IsStdDropDefaultClass(*TSTdecl);
3873 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3875 const int nArgs = tArgs.size();
3876 const int nNormArgs = normalizedTst->getNumArgs();
3878 bool mightHaveChanged =
false;
3881 for (
int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
3882 const NamedDecl* tParPtr = tPars.getParam(formal);
3884 Error(
"KeepNParams",
"The parameter number %s is null.\n", formal);
3891 if (formal == nNormArgs || inst == nNormArgs)
break;
3893 const TemplateArgument& tArg = tArgs.get(formal);
3894 TemplateArgument normTArg(normalizedTst->getArgs()[inst]);
3896 bool shouldKeepArg = nArgsToKeep < 0 || inst < nArgsToKeep;
3897 if (isStdDropDefault) shouldKeepArg =
false;
3906 if ( tParPtr->isTemplateParameterPack() ) {
3911 for( ; inst != nNormArgs; ++inst) {
3912 normTArg = normalizedTst->getArgs()[inst];
3914 argsToKeep.push_back(normTArg);
3920 argsToKeep.push_back(normTArg);
3923 if (!isStdDropDefault) {
3925 mightHaveChanged =
true;
3935 auto argKind = tArg.getKind();
3936 if (argKind == clang::TemplateArgument::Type){
3938 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3939 }
else if (argKind == clang::TemplateArgument::Integral){
3944 argsToKeep.push_back(normTArg);
3946 mightHaveChanged =
true;
3952 if (!prefix_changed && !mightHaveChanged) {
3953 normalizedType = originalNormalizedType;
3958 if (mightHaveChanged) {
3959 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3960 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3962 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3963 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3969 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3970 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3984 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3987 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3988 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt,
type, normCtxt.
GetConfig(),
true );
3996 return normalizedType;
4010 if (
type.isNull()) {
4017 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
4018 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
4019 policy.SuppressTagKeyword =
true;
4020 policy.SuppressScope =
true;
4021 policy.AnonymousTagLocations =
false;
4026 std::string normalizedNameStep1;
4029 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
4030 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
4040 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
4041 norm_name.erase(0,2);
4049 const clang::TypeDecl* typeDecl,
4050 const cling::Interpreter &interpreter)
4053 const clang::Sema &sema = interpreter.getSema();
4054 clang::ASTContext& astCtxt = sema.getASTContext();
4055 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
4064std::pair<std::string,clang::QualType>
4066 const cling::Interpreter &interpreter,
4070 std::string thisTypeName;
4071 GetNormalizedName(thisTypeName, thisType, interpreter, normCtxt );
4074 if (!hasChanged)
return std::make_pair(thisTypeName,thisType);
4078 "Name changed from %s to %s\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
4081 auto& lookupHelper = interpreter.getLookupHelper();
4083 const clang::Type* typePtrForIO;
4084 lookupHelper.findScope(thisTypeNameForIO,
4085 cling::LookupHelper::DiagSetting::NoDiagnostics,
4089 if (!typePtrForIO) {
4091 "Type not found: %s.",thisTypeNameForIO.c_str());
4094 clang::QualType typeForIO(typePtrForIO,0);
4097 if (!typeForIO->isRecordType()) {
4098 return std::make_pair(thisTypeNameForIO,typeForIO);
4101 auto thisDeclForIO = typeForIO->getAsCXXRecordDecl();
4102 if (!thisDeclForIO) {
4104 "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());
4105 return std::make_pair(thisTypeName,thisType);
4108 return std::make_pair(thisTypeNameForIO,typeForIO);
4114 const cling::Interpreter &interpreter,
4126 std::string dictFileName(moduleName);
4127 dictFileName +=
"_rdict.pcm";
4128 return dictFileName;
4132 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4158 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4159 clang::SourceLocation sourceLocation = decl.getEndLoc();
4162 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
4170 if (!decl.hasOwningModule() && sourceManager.isLoadedSourceLocation(sourceLocation)) {
4176 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4180 bool skipToSemi =
true;
4181 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4182 if (FD->isImplicit()) {
4186 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4190 }
else if (FD->doesThisDeclarationHaveABody()) {
4193 assert((decl.getEndLoc() != sourceLocation || *commentStart ==
'}'
4195 &&
"Expected macro or end of body at '}'");
4196 if (*commentStart) ++commentStart;
4199 while (*commentStart && isspace(*commentStart)
4200 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4203 if (*commentStart ==
';') ++commentStart;
4207 }
else if (
const clang::EnumConstantDecl* ECD
4208 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4210 if (ECD->getNextDeclInContext())
4211 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4219 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4221 if (*commentStart ==
';') ++commentStart;
4225 while ( *commentStart && isspace(*commentStart)
4226 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4230 if (commentStart[0] !=
'/' ||
4231 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4241 unsigned int skipChars = 2;
4242 if (commentStart[0] ==
'/' &&
4243 commentStart[1] ==
'/' &&
4244 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4245 commentStart[3] ==
'<') {
4247 }
else if (commentStart[0] ==
'/' &&
4248 commentStart[1] ==
'*' &&
4249 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4250 commentStart[3] ==
'<') {
4254 commentStart += skipChars;
4257 while ( *commentStart && isspace(*commentStart)
4258 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4261 const char* commentEnd = commentStart;
4263 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4269 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4275 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4276 *loc = sourceLocation.getLocWithOffset(
offset - 1);
4279 return llvm::StringRef(commentStart, commentEnd - commentStart);
4287 if (!decl)
return false;
4289 auto& sema = interpreter.getCI()->getSema();
4290 auto maybeMacroLoc = decl->getLocation();
4292 if (!maybeMacroLoc.isMacroID())
return false;
4294 static const std::vector<std::string> signatures =
4295 {
"ClassDef",
"ClassDefOverride",
"ClassDefNV",
"ClassDefInline",
"ClassDefInlineOverride",
"ClassDefInlineNV" };
4297 for (
auto &
name : signatures)
4298 if (sema.findMacroSpelling(maybeMacroLoc,
name))
4312 clang::SourceLocation *loc,
4313 const cling::Interpreter &interpreter)
4315 using namespace clang;
4317 const Decl* DeclFileLineDecl
4318 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4319 cling::LookupHelper::NoDiagnostics);
4323 SourceLocation commentSLoc;
4325 if (comment.size()) {
4332 return llvm::StringRef();
4341 const clang::Type *rawtype =
type.getTypePtr();
4344 if (rawtype->isElaboratedTypeSpecifier() ) {
4345 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4347 if (rawtype->isArrayType()) {
4348 rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
4350 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4352 clang::QualType pointee;
4353 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4355 rawtype = pointee.getTypePtr();
4357 if (rawtype->isElaboratedTypeSpecifier() ) {
4358 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4360 if (rawtype->isArrayType()) {
4361 rawtype = rawtype->getBaseElementTypeUnsafe ();
4365 if (rawtype->isArrayType()) {
4366 rawtype = rawtype->getBaseElementTypeUnsafe ();
4376 return cling::utils::Analyze::IsStdClass(cl);
4386 if (cling::utils::Analyze::IsStdClass(cl)) {
4387 static const char *names[] =
4388 {
"shared_ptr",
"__shared_ptr",
4389 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4390 llvm::StringRef clname(cl.getName());
4391 for(
auto &&
name : names) {
4392 if (clname ==
name)
return true;
4402 const clang::CXXRecordDecl ¤tCl)
4405 if (&cl == ¤tCl)
return true;
4407 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4410 if (NULL == previous){
4429 const clang::CXXRecordDecl *thisDecl =
4430 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4434 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4439 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4464 if (!IsStdClass(cl)) {
4465 auto *nsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext());
4466 if (cl.getName() !=
"RVec" || nsDecl ==
nullptr || nsDecl->getName() !=
"VecOps")
4469 auto *parentNsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext()->getParent());
4470 if (parentNsDecl ==
nullptr || parentNsDecl->getName() !=
"ROOT")
4474 return STLKind(cl.getName());
4478 using namespace clang;
4479 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4480 bool VisitTypedefType(
const TypedefType* TD) {
4483 bool VisitArrayType(
const ArrayType* AT) {
4484 return Visit(AT->getElementType().getTypePtr());
4486 bool VisitDecltypeType(
const DecltypeType* DT) {
4487 return Visit(DT->getUnderlyingType().getTypePtr());
4489 bool VisitPointerType(
const PointerType* PT) {
4490 return Visit(PT->getPointeeType().getTypePtr());
4492 bool VisitReferenceType(
const ReferenceType* RT) {
4493 return Visit(RT->getPointeeType().getTypePtr());
4495 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4496 return Visit(STST->getReplacementType().getTypePtr());
4498 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4499 for (
int I = 0,
N = TST->getNumArgs();
I <
N; ++
I) {
4500 const TemplateArgument&
TA = TST->getArg(
I);
4501 if (
TA.getKind() == TemplateArgument::Type
4502 && Visit(
TA.getAsType().getTypePtr()))
4507 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4510 bool VisitTypeOfType(
const TypeOfType* TOT) {
4511 return TOT->getUnderlyingType().getTypePtr();
4513 bool VisitElaboratedType(
const ElaboratedType* ET) {
4514 NestedNameSpecifier* NNS = ET->getQualifier();
4516 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4517 if (Visit(NNS->getAsType()))
4520 NNS = NNS->getPrefix();
4522 return Visit(ET->getNamedType().getTypePtr());
4537 if (!instance)
return input;
4543 using namespace llvm;
4544 using namespace clang;
4545 const clang::ASTContext &Ctxt = instance->getAsCXXRecordDecl()->getASTContext();
4548 const clang::ElaboratedType* etype
4549 = llvm::dyn_cast<clang::ElaboratedType>(
input.getTypePtr());
4553 clang::Qualifiers scope_qualifiers =
input.getLocalQualifiers();
4554 assert(instance->getAsCXXRecordDecl()!=0 &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4556 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),instance);
4557 clang::QualType subTy =
ReSubstTemplateArg(clang::QualType(etype->getNamedType().getTypePtr(),0),instance);
4559 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4560 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4564 QualType QT =
input;
4568 if (isa<clang::PointerType>(QT.getTypePtr())) {
4570 Qualifiers quals = QT.getQualifiers();
4573 if (nQT == QT->getPointeeType())
return QT;
4575 QT = Ctxt.getPointerType(nQT);
4577 QT = Ctxt.getQualifiedType(QT, quals);
4583 if (isa<ReferenceType>(QT.getTypePtr())) {
4585 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4586 Qualifiers quals = QT.getQualifiers();
4589 if (nQT == QT->getPointeeType())
return QT;
4593 QT = Ctxt.getLValueReferenceType(nQT);
4595 QT = Ctxt.getRValueReferenceType(nQT);
4597 QT = Ctxt.getQualifiedType(QT, quals);
4603 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4605 Qualifiers quals = QT.getQualifiers();
4607 if (
const auto arr = dyn_cast<ConstantArrayType>(QT.getTypePtr())) {
4610 if (newQT == arr->getElementType())
return QT;
4611 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();
4655 if (!instance)
return input;
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) {
4691 if (instanceArgs[A].getKind() == clang::TemplateArgument::Type) {
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);
4726 instance->dump(ostream, Ctxt);
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() ) {
4744 }
else if (TST->getArg(
index).getKind() == clang::TemplateArgument::Type) {
4745 return TST->getArg(
index).getAsType();
4754 const clang::TemplateSpecializationType* inputTST
4755 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
input.getTypePtr());
4756 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4759 bool mightHaveChanged =
false;
4760 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4761 for(clang::TemplateSpecializationType::iterator
I = inputTST->begin(), E = inputTST->end();
4763 if (
I->getKind() != clang::TemplateArgument::Type) {
4764 desArgs.push_back(*
I);
4768 clang::QualType SubTy =
I->getAsType();
4770 if (llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4771 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4773 mightHaveChanged = SubTy != newSubTy;
4774 if (!newSubTy.isNull()) {
4775 desArgs.push_back(clang::TemplateArgument(newSubTy));
4778 desArgs.push_back(*
I);
4782 if (mightHaveChanged) {
4783 clang::Qualifiers qualifiers =
input.getLocalQualifiers();
4784 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4786 inputTST->getCanonicalTypeInternal());
4787 input = astCtxt.getQualifiedType(
input, qualifiers);
4799 if ( nArgsToRemove == 0 ||
name ==
"")
4806 unsigned int nArgsRemoved=0;
4807 unsigned int nBraces=0;
4809 while (nArgsRemoved!=nArgsToRemove && cur<
length){
4811 if (
c ==
'<') nBraces++;
4812 if (
c ==
'>') nBraces--;
4813 if (
c ==
',' && nBraces==1 ) nArgsRemoved++;
4827 static const char *stls[] =
4828 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4829 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
"RVec", 0};
4843 for(
int k=1;stls[k];k++) {
if (
type.equals(stls[k]))
return values[k];}
4854 TND = TND->getMostRecentDecl();
4855 while (TND && !(TND->hasAttrs()))
4856 TND = TND->getPreviousDecl();
4868 TD = TD->getMostRecentDecl();
4869 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4870 TD = TD->getPreviousDecl();
4879 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4881 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4882 if (!enclosingNamespaceDeclCtxt)
return;
4884 const clang::NamespaceDecl* enclosingNamespace =
4885 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4886 if (!enclosingNamespace)
return;
4888 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4889 enclosingNamespace->isInline()));
4899 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4901 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4904 if (!enclosingNamespaceDeclCtxt) {
4910 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4911 if (!enclosingNamespace)
return;
4914 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4915 enclosingNamespace->isInline()));
4926 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4928 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4929 if (!enclosingDeclCtxt)
return nullptr;
4931 unsigned int scopeType;
4933 if (
auto enclosingNamespacePtr =
4934 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4935 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4936 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4940 if (
auto enclosingClassPtr =
4941 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4942 return enclosingClassPtr;
4954 std::string::size_type beginVar = 0;
4955 std::string::size_type endVar = 0;
4956 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4957 && beginVar + 1 < txt.length()) {
4958 std::string::size_type beginVarName = beginVar + 1;
4959 std::string::size_type endVarName = std::string::npos;
4960 if (txt[beginVarName] ==
'(') {
4962 endVarName = txt.find(
')', beginVarName);
4964 if (endVarName == std::string::npos) {
4966 varname, txt.c_str() + beginVar);
4969 endVar = endVarName + 1;
4972 beginVarName = beginVar + 1;
4973 endVarName = beginVarName;
4974 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
4976 endVar = endVarName;
4979 const char* val = getenv(txt.substr(beginVarName,
4980 endVarName - beginVarName).c_str());
4983 txt.replace(beginVar, endVar - beginVar, val);
4984 int lenval = strlen(val);
4985 int delta = lenval - (endVar - beginVar);
4989 beginVar = endVar + 1;
5001 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
5005 std::istringstream envInclPathsStream(envInclPath);
5006 std::string inclPath;
5007 while (std::getline(envInclPathsStream, inclPath,
':')) {
5010 if (!inclPath.empty()) {
5011 clingArgs.push_back(
"-I");
5012 clingArgs.push_back(inclPath);
5023 size_t start_pos = 0;
5028 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
5029 str.replace(start_pos, from.length(), to);
5030 start_pos += to.length();
5031 if (recurse) changed =
true;
5047 if (theString.size() < theSubstring.size())
return false;
5048 const unsigned int theSubstringSize = theSubstring.size();
5049 return 0 == theString.compare(theString.size() - theSubstringSize,
5058 if (theString.size() < theSubstring.size())
return false;
5059 const unsigned int theSubstringSize = theSubstring.size();
5060 return 0 == theString.compare(0,
5078 size_t linkdeflen = 9;
5080 if (0 == strncasecmp(
filename + (
len - linkdeflen),
"linkdef", linkdeflen - 2)
5096 return llvm::sys::path::extension(
filename) ==
".h" ||
5097 llvm::sys::path::extension(
filename) ==
".hh" ||
5098 llvm::sys::path::extension(
filename) ==
".hpp" ||
5099 llvm::sys::path::extension(
filename) ==
".H" ||
5100 llvm::sys::path::extension(
filename) ==
".h++" ||
5101 llvm::sys::path::extension(
filename) ==
"hxx" ||
5102 llvm::sys::path::extension(
filename) ==
"Hxx" ||
5103 llvm::sys::path::extension(
filename) ==
"HXX";
5109 cling::Interpreter::IgnoreFilesFunc_t ignoreFiles,
5110 const cling::Interpreter &interp,
5113 clang::Sema &sema = interp.getSema();
5114 cling::Transaction theTransaction(sema);
5115 std::set<clang::Decl *> addedDecls;
5116 for (
auto decl : decls) {
5118 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
5119 theTransaction.append(ncDecl);
5121 std::string newFwdDecl;
5122 llvm::raw_string_ostream llvmOstr(newFwdDecl);
5124 std::string locallogs;
5125 llvm::raw_string_ostream llvmLogStr(locallogs);
5126 interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr,
true,
5127 logs ? &llvmLogStr : nullptr, ignoreFiles);
5131 logs->swap(locallogs);
5143 std::string& defString)
5155 std::string& defString)
5157 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5160 if (rcdPtr)
return rcdPtr;
5163 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5165 std::string scopeName;
5166 std::string scopeContent;
5167 unsigned int scopeIndex;
5168 for (
auto const & encScope : enclosingNamespaces){
5169 scopeIndex = encScope.second;
5170 scopeName = encScope.first;
5171 scopeContent =
" { " + defString +
" }";
5172 defString = scopeType[scopeIndex] +
5194 const clang::TemplateParameterList& tmplParamList,
5195 const cling::Interpreter& interpreter)
5198 for (
auto prmIt = tmplParamList.begin();
5199 prmIt != tmplParamList.end(); prmIt++){
5201 if (prmIt != tmplParamList.begin())
5202 templateArgs +=
", ";
5204 auto nDecl = *prmIt;
5205 std::string typeName;
5208 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5209 typeName =
"typename ";
5210 if (nDecl->isParameterPack())
5212 typeName += (*prmIt)->getNameAsString();
5215 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5216 auto theType = nttpd->getType();
5219 if (theType.getAsString().find(
"enum") != std::string::npos){
5220 std::string astDump;
5221 llvm::raw_string_ostream ostream(astDump);
5222 nttpd->dump(ostream);
5224 ROOT::TMetaUtils::Warning(0,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5233 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5236 std::string astDump;
5237 llvm::raw_string_ostream ostream(astDump);
5238 ttpd->dump(ostream);
5240 ROOT::TMetaUtils::Error(0,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5245 templateArgs += typeName;
5256 const cling::Interpreter& interpreter,
5257 std::string& defString)
5259 std::string templatePrefixString;
5260 auto tmplParamList= templDecl.getTemplateParameters();
5261 if (!tmplParamList){
5263 "Cannot extract template parameter list for %s",
5264 templDecl.getNameAsString().c_str());
5271 "Problems with arguments for forward declaration of class %s\n",
5272 templDecl.getNameAsString().c_str());
5275 templatePrefixString =
"template " + templatePrefixString +
" ";
5277 defString = templatePrefixString +
"class ";
5278 if (templDecl.isParameterPack())
5279 defString +=
"... ";
5280 defString += templDecl.getNameAsString();
5281 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5295 std::string& argFwdDecl,
5296 const cling::Interpreter& interpreter,
5297 bool acceptStl=
false)
5303 if (clang::TemplateArgument::Type != arg.getKind())
return 0;
5305 auto argQualType = arg.getAsType();
5308 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5310 auto argTypePtr = argQualType.getTypePtr();
5313 if (llvm::isa<clang::EnumType>(argTypePtr)){
5318 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5323 if (
auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr)) {
5324 FwdDeclFromTypeDefNameDecl(*tdTypePtr->getDecl(), interpreter, argFwdDecl);
5328 if (
auto argRecTypePtr = llvm::dyn_cast<clang::RecordType>(argTypePtr)){
5330 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5331 FwdDeclFromRcdDecl(*argRecDeclPtr,interpreter,argFwdDecl,acceptStl);
5343 const cling::Interpreter& interpreter,
5344 std::string& defString,
5345 const std::string &normalizedName)
5349 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)) {
5350 if (
const auto *specDef = tmplSpecDeclPtr->getDefinition()) {
5351 if (specDef->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization)
5355 std::cout <<
" Forward declaring template spec " << normalizedName <<
":\n";
5356 for (
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()) {
5357 std::string argFwdDecl;
5360 std::cout <<
" o Template argument ";
5362 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5364 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5371 defString += argFwdDecl +
'\n';
5373 defString +=
"template <> class " + normalizedName +
';';
5387 const cling::Interpreter& interpreter,
5388 std::string& defString,
5396 if (!recordDecl.getIdentifier())
5400 std::string argsFwdDecl;
5402 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5403 std::string argFwdDecl;
5405 std::cout <<
"Class " << recordDecl.getNameAsString()
5406 <<
" is a template specialisation. Treating its arguments.\n";
5407 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5410 std::cout <<
" o Template argument ";
5412 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5414 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5421 argsFwdDecl+=argFwdDecl;
5425 defString=argsFwdDecl;
5430 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5433 defString = argsFwdDecl +
"\n" + defString;
5438 defString =
"class " + recordDecl.getNameAsString() +
";";
5439 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5447 defString = argsFwdDecl +
"\n" + defString;
5458 const cling::Interpreter& interpreter,
5459 std::string& fwdDeclString,
5460 std::unordered_set<std::string>* fwdDeclSetPtr)
5462 std::string buffer = tdnDecl.getNameAsString();
5463 std::string underlyingName;
5464 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5465 if (
const clang::TagType* TT
5466 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5467 if (clang::NamedDecl* ND = TT->getDecl()) {
5468 if (!ND->getIdentifier()) {
5482 if (underlyingName.find(
">::") != std::string::npos)
5485 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5497 auto& ctxt = tdnDecl.getASTContext();
5498 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5500 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5501 std::string tdnFwdDecl;
5502 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5507 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5508 fwdDeclString+=tdnFwdDecl;
5509 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5510 std::string classFwdDecl;
5512 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: "
5513 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5522 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5523 fwdDeclString+=classFwdDecl;
5526 fwdDeclString+=buffer;
5538 std::string& valAsString,
5539 const clang::PrintingPolicy& ppolicy)
5541 auto defArgExprPtr = par.getDefaultArg();
5542 auto& ctxt = par.getASTContext();
5543 if(!defArgExprPtr->isEvaluatable(ctxt)){
5547 auto defArgType = par.getType();
5550 if (defArgType->isBooleanType()){
5552 defArgExprPtr->EvaluateAsBooleanCondition (
result,ctxt);
5553 valAsString=std::to_string(
result);
5558 if (defArgType->isIntegerType()){
5559 clang::Expr::EvalResult evalResult;
5560 defArgExprPtr->EvaluateAsInt(evalResult, ctxt);
5561 llvm::APSInt
result = evalResult.Val.getInt();
5562 auto uintVal = *
result.getRawData();
5563 if (
result.isNegative()){
5564 long long int intVal=uintVal*-1;
5565 valAsString=std::to_string(intVal);
5567 valAsString=std::to_string(uintVal);
5574 llvm::raw_string_ostream rso(valAsString);
5575 defArgExprPtr->printPretty(rso,
nullptr,ppolicy);
5576 valAsString = rso.str();
The file contains utilities which are foundational and could be used across the core component of ROO...
#define R(a, b, c, d, e, f, g, h, i)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static void indent(ostringstream &buf, int indent_level)
static bool RecurseKeepNParams(clang::TemplateArgument &normTArg, const clang::TemplateArgument &tArg, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const clang::ASTContext &astCtxt)
static clang::SourceLocation getFinalSpellingLoc(clang::SourceManager &sourceManager, clang::SourceLocation sourceLoc)
const clang::DeclContext * GetEnclosingSpace(const clang::RecordDecl &cl)
bool IsTemplate(const clang::Decl &cl)
static void KeepNParams(clang::QualType &normalizedType, const clang::QualType &vanillaType, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
This function allows to manipulate the number of arguments in the type of a template specialisation.
static void CreateNameTypeMap(const clang::CXXRecordDecl &cl, ROOT::MembersTypeMap_t &nameType)
Create the data member name-type map for given class.
const clang::CXXMethodDecl * GetMethodWithProto(const clang::Decl *cinfo, const char *method, const char *proto, const cling::Interpreter &interp, bool diagnose)
int dumpDeclForAssert(const clang::Decl &D, const char *commentStart)
static void replaceEnvVars(const char *varname, std::string &txt)
Reimplementation of TSystem::ExpandPathName() that cannot be used from TMetaUtils.
static bool areEqualValues(const clang::TemplateArgument &tArg, const clang::NamedDecl &tPar)
std::cout << "Are equal values?\n";
static bool isTypeWithDefault(const clang::NamedDecl *nDecl)
Check if this NamedDecl is a template parameter with a default argument.
static int TreatSingleTemplateArg(const clang::TemplateArgument &arg, std::string &argFwdDecl, const cling::Interpreter &interpreter, bool acceptStl=false)
static bool areEqualTypes(const clang::TemplateArgument &tArg, llvm::SmallVectorImpl< clang::TemplateArgument > &preceedingTArgs, const clang::NamedDecl &tPar, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)